diff --git a/Gopkg.lock b/Gopkg.lock
index d7e39752628439460aa8c3a026c00903ffe5de30..ab8a14a5b6a15522ff240dea6a783264b227c6ed 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -124,6 +124,12 @@
   revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
   version = "v1.2.0"
 
+[[projects]]
+  branch = "master"
+  name = "github.com/howeyc/gopass"
+  packages = ["."]
+  revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
+
 [[projects]]
   name = "github.com/imdario/mergo"
   packages = ["."]
@@ -349,22 +355,6 @@
   revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab"
   version = "v1.1.1"
 
-[[projects]]
-  name = "github.com/wayn3h0/go-uuid"
-  packages = [
-    ".",
-    "internal/dcesecurity",
-    "internal/layout",
-    "internal/namebased",
-    "internal/namebased/md5",
-    "internal/namebased/sha1",
-    "internal/random",
-    "internal/timebased",
-    "internal/version"
-  ]
-  revision = "1622016a49b50139b1ac263e6ef2804226b3dec6"
-  version = "v2.2.1"
-
 [[projects]]
   branch = "master"
   name = "golang.org/x/crypto"
@@ -376,9 +366,12 @@
     "nacl/secretbox",
     "openpgp/armor",
     "openpgp/errors",
+    "pbkdf2",
     "poly1305",
     "ripemd160",
-    "salsa20/salsa"
+    "salsa20/salsa",
+    "scrypt",
+    "ssh/terminal"
   ]
   revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e"
 
@@ -399,7 +392,10 @@
 [[projects]]
   branch = "master"
   name = "golang.org/x/sys"
-  packages = ["unix"]
+  packages = [
+    "unix",
+    "windows"
+  ]
   revision = "3b87a42e500a6dc65dae1a55d0b641295971163e"
 
 [[projects]]
@@ -474,6 +470,6 @@
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "a434dee26127011ec236d80b300051d321f012ce49cd77b1112034c15e54ac3e"
+  inputs-digest = "2a58c6e6ec7d2792452873c5cb57032cc6d1a4750345647f562a8c9e8bc1e0b4"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Makefile b/Makefile
index 87ea9c00f2fc86a3c0d90ef1f44cd900512008c1..649eb0996a05b3c240751e5e99f8da386b1a8a18 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,9 @@ megacheck:
 	@go get honnef.co/go/tools/cmd/megacheck
 	@for pkg in ${PACKAGES_NOVENDOR}; do megacheck "$$pkg"; done
 
+keys/pbkeys/keys.pb.go: keys/pbkeys/keys.proto
+	@protoc -I ./keys/pbkeys keys/pbkeys/keys.proto --go_out=plugins=grpc:keys/pbkeys
+
 ### Dependency management for github.com/hyperledger/burrow
 
 # erase vendor wipes the full vendor directory
@@ -153,10 +156,12 @@ docker_build: check commit_hash
 test: check
 	@go test ${PACKAGES_NOVENDOR}
 
+.PHONY: test_keys
+test_keys: build_db
+	burrow_bin="${REPO}/bin/burrow" keys/test.sh
+
 .PHONY: test_integration
-test_integration:
-	@go get github.com/monax/bosmarmot/keys/cmd/monax-keys
-	@go test -tags integration ./keys/integration
+test_integration: test_keys
 	@go test -tags integration ./rpc/v0/integration
 	@go test -tags integration ./rpc/tm/integration
 
diff --git a/README.md b/README.md
index 1ff2670552b7e9bd5b9c16073e18b0d17eab619e..5fc0fc853096d703d8ad6445a1c7a2fe15a78163 100644
--- a/README.md
+++ b/README.md
@@ -42,18 +42,6 @@ The end result will be a `burrow.toml` that will be read in from your current wo
 
 ### Configuration
 
-#### Install monax-keys
-Monax-keys is our key-signing daemon. In a future release this will be merged with Burrow and will support a GPG backend
-in addition to the development mode that monax-keys currently supplies.
-
-We need to run monax-keys so that `burrow configure` can generate keys for us in the following step.
-```shell
-# Install monax-keys
-go get -u github.com/monax/bosmarmot/keys/cmd/monax-keys
-# run monax-keys server in background
-monax-keys server &
-```
-
 #### Configure Burrow
 The quick-and-dirty one-liner looks like:
 
diff --git a/account/account.go b/account/account.go
index 725eda71a79ebc99cbf849ece47cee5f22f877a1..0985f38d77905b3c4280b1529f4106678ce80251 100644
--- a/account/account.go
+++ b/account/account.go
@@ -18,36 +18,20 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
-	"io"
 
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/tendermint/go-wire"
 )
 
-var GlobalPermissionsAddress = Address(binary.Zero160)
-
-// Signable is an interface for all signable things.
-// It typically removes signatures before serializing.
-type Signable interface {
-	WriteSignBytes(chainID string, w io.Writer, n *int, err *error)
-}
-
-// SignBytes is a convenience method for getting the bytes to sign of a Signable.
-func SignBytes(chainID string, o Signable) []byte {
-	buf, n, err := new(bytes.Buffer), new(int), new(error)
-	o.WriteSignBytes(chainID, buf, n, err)
-	if *err != nil {
-		panic(fmt.Sprintf("could not write sign bytes for a signable: %s", *err))
-	}
-	return buf.Bytes()
-}
+var GlobalPermissionsAddress = crypto.Address(binary.Zero160)
 
 type Addressable interface {
 	// Get the 20 byte EVM address of this account
-	Address() Address
+	Address() crypto.Address
 	// Public key from which the Address is derived
-	PublicKey() PublicKey
+	PublicKey() crypto.PublicKey
 }
 
 // The default immutable interface to an account
@@ -75,7 +59,7 @@ type Account interface {
 type MutableAccount interface {
 	Account
 	// Set public key (needed for lazy initialisation), should also set the dependent address
-	SetPublicKey(pubKey PublicKey) MutableAccount
+	SetPublicKey(pubKey crypto.PublicKey) MutableAccount
 	// Subtract amount from account balance (will panic if amount is greater than balance)
 	SubtractFromBalance(amount uint64) (MutableAccount, error)
 	// Add amount to balance (will panic if amount plus balance is a uint64 overflow)
@@ -99,8 +83,8 @@ type MutableAccount interface {
 
 // ConcreteAccount is the canonical serialisation and bash-in-place object for an Account
 type ConcreteAccount struct {
-	Address     Address
-	PublicKey   PublicKey
+	Address     crypto.Address
+	PublicKey   crypto.PublicKey
 	Sequence    uint64
 	Balance     uint64
 	Code        Bytecode
@@ -108,7 +92,7 @@ type ConcreteAccount struct {
 	Permissions ptypes.AccountPermissions
 }
 
-func NewConcreteAccount(pubKey PublicKey) ConcreteAccount {
+func NewConcreteAccount(pubKey crypto.PublicKey) ConcreteAccount {
 	return ConcreteAccount{
 		Address:   pubKey.Address(),
 		PublicKey: pubKey,
@@ -122,7 +106,7 @@ func NewConcreteAccount(pubKey PublicKey) ConcreteAccount {
 }
 
 func NewConcreteAccountFromSecret(secret string) ConcreteAccount {
-	return NewConcreteAccount(PrivateKeyFromSecret(secret).PublicKey())
+	return NewConcreteAccount(crypto.PrivateKeyFromSecret(secret, crypto.CurveTypeEd25519).GetPublicKey())
 }
 
 // Return as immutable Account
@@ -230,11 +214,11 @@ type concreteAccountWrapper struct {
 
 var _ Account = concreteAccountWrapper{}
 
-func (caw concreteAccountWrapper) Address() Address {
+func (caw concreteAccountWrapper) Address() crypto.Address {
 	return caw.ConcreteAccount.Address
 }
 
-func (caw concreteAccountWrapper) PublicKey() PublicKey {
+func (caw concreteAccountWrapper) PublicKey() crypto.PublicKey {
 	return caw.ConcreteAccount.PublicKey
 }
 
@@ -273,7 +257,7 @@ func (caw concreteAccountWrapper) MarshalJSON() ([]byte, error) {
 // Account mutation via MutableAccount interface
 var _ MutableAccount = concreteAccountWrapper{}
 
-func (caw concreteAccountWrapper) SetPublicKey(pubKey PublicKey) MutableAccount {
+func (caw concreteAccountWrapper) SetPublicKey(pubKey crypto.PublicKey) MutableAccount {
 	caw.ConcreteAccount.PublicKey = pubKey
 	addressFromPubKey := pubKey.Address()
 	// We don't want the wrong public key to take control of an account so we panic here
diff --git a/account/account_test.go b/account/account_test.go
index aaffb2ff882fb8b60a85e2160e40138f2cf8ce19..ca3e41fdba161931d24a8610ded01aee33301110 100644
--- a/account/account_test.go
+++ b/account/account_test.go
@@ -21,11 +21,11 @@ import (
 
 	"fmt"
 
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/permission/types"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 )
 
@@ -36,7 +36,7 @@ func TestAddress(t *testing.T) {
 		1, 2, 3, 4, 5,
 		1, 2, 3, 4, 5,
 	}
-	addr, err := AddressFromBytes(bs)
+	addr, err := crypto.AddressFromBytes(bs)
 	assert.NoError(t, err)
 	word256 := addr.Word256()
 	leadingZeroes := []byte{
@@ -45,7 +45,7 @@ func TestAddress(t *testing.T) {
 		0, 0, 0, 0,
 	}
 	assert.Equal(t, leadingZeroes, word256[:12])
-	addrFromWord256 := AddressFromWord256(word256)
+	addrFromWord256 := crypto.AddressFromWord256(word256)
 	assert.Equal(t, bs, addrFromWord256[:])
 	assert.Equal(t, addr, addrFromWord256)
 }
@@ -118,11 +118,10 @@ func TestMarshalJSON(t *testing.T) {
 	acc := concreteAcc.Account()
 	bs, err := json.Marshal(acc)
 
-	pubKeyEd25519 := concreteAcc.PublicKey.PubKey.Unwrap().(crypto.PubKeyEd25519)
-	expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"type":"ed25519","data":"%X"},`+
+	expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"CurveType":"ed25519","PublicKey":"%s"},`+
 		`"Sequence":0,"Balance":0,"Code":"3C172D","StorageRoot":"",`+
 		`"Permissions":{"Base":{"Perms":0,"SetBit":0},"Roles":[]}}`,
-		concreteAcc.Address, pubKeyEd25519[:])
+		concreteAcc.Address, concreteAcc.PublicKey)
 	assert.Equal(t, expected, string(bs))
 	assert.NoError(t, err)
 }
diff --git a/account/crypto.go b/account/crypto.go
deleted file mode 100644
index 942901a39c65cf55b970e91aba8cf5f82cba8977..0000000000000000000000000000000000000000
--- a/account/crypto.go
+++ /dev/null
@@ -1,251 +0,0 @@
-package account
-
-import (
-	"bytes"
-	"crypto/rand"
-	"crypto/sha256"
-	"fmt"
-	"io"
-
-	"github.com/tendermint/go-crypto"
-	"golang.org/x/crypto/ed25519"
-)
-
-// The types in this file allow us to control serialisation of keys and signatures, as well as the interface
-// exposed regardless of crypto library
-
-type Signer interface {
-	Sign(msg []byte) (Signature, error)
-}
-
-// PublicKey
-type PublicKey struct {
-	crypto.PubKey `json:"unwrap"`
-}
-
-func PublicKeyFromGoCryptoPubKey(pubKey crypto.PubKey) (PublicKey, error) {
-	_, err := AddressFromBytes(pubKey.Address())
-	if err != nil {
-		return PublicKey{}, fmt.Errorf("could not make valid address from public key %v: %v", pubKey, err)
-	}
-	return PublicKey{
-		PubKey: pubKey,
-	}, nil
-}
-
-// Currently this is a stub that reads the raw bytes returned by key_client and returns
-// an ed25519 public key.
-func PublicKeyFromBytes(bs []byte) (PublicKey, error) {
-	//TODO: read a typed representation (most likely JSON) and do the right thing here
-	// Only supports ed25519 currently so no switch on signature scheme
-	pubKeyEd25519 := crypto.PubKeyEd25519{}
-	if len(bs) != len(pubKeyEd25519) {
-		return PublicKey{}, fmt.Errorf("bytes passed have length %v by ed25519 public keys have %v bytes",
-			len(bs), len(pubKeyEd25519))
-	}
-	copy(pubKeyEd25519[:], bs)
-	return PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap())
-}
-
-// Returns a copy of the raw untyped public key bytes
-func (pk PublicKey) RawBytes() []byte {
-	switch pubKey := pk.PubKey.Unwrap().(type) {
-	case crypto.PubKeyEd25519:
-		pubKeyCopy := crypto.PubKeyEd25519{}
-		copy(pubKeyCopy[:], pubKey[:])
-		return pubKeyCopy[:]
-	case crypto.PubKeySecp256k1:
-		pubKeyCopy := crypto.PubKeySecp256k1{}
-		copy(pubKeyCopy[:], pubKey[:])
-		return pubKeyCopy[:]
-	default:
-		return nil
-	}
-}
-
-func (pk PublicKey) VerifyBytes(msg []byte, signature Signature) bool {
-	return pk.PubKey.VerifyBytes(msg, signature.Signature)
-}
-
-func (pk PublicKey) Address() Address {
-	// We check this on initialisation to avoid this panic, but returning an error here is ugly and caching
-	// the address on PublicKey initialisation breaks go-wire serialisation since with unwrap we can only have one field.
-	// We can do something better with better serialisation
-	return MustAddressFromBytes(pk.PubKey.Address())
-}
-
-func (pk PublicKey) MarshalJSON() ([]byte, error) {
-	return pk.PubKey.MarshalJSON()
-}
-
-func (pk *PublicKey) UnmarshalJSON(data []byte) error {
-	return pk.PubKey.UnmarshalJSON(data)
-}
-
-func (pk PublicKey) MarshalText() ([]byte, error) {
-	return pk.MarshalJSON()
-}
-
-func (pk *PublicKey) UnmarshalText(text []byte) error {
-	return pk.UnmarshalJSON(text)
-}
-
-// PrivateKey
-
-type PrivateKey struct {
-	crypto.PrivKey `json:"unwrap"`
-}
-
-func PrivateKeyFromGoCryptoPrivKey(privKey crypto.PrivKey) (PrivateKey, error) {
-	_, err := PublicKeyFromGoCryptoPubKey(privKey.PubKey())
-	if err != nil {
-		return PrivateKey{}, fmt.Errorf("could not create public key from private key: %v", err)
-	}
-	return PrivateKey{
-		PrivKey: privKey,
-	}, nil
-}
-
-func PrivateKeyFromSecret(secret string) PrivateKey {
-	hasher := sha256.New()
-	hasher.Write(([]byte)(secret))
-	// No error from a buffer
-	privateKey, _ := GeneratePrivateKey(bytes.NewBuffer(hasher.Sum(nil)))
-	return privateKey
-}
-
-// Generates private key from a source of random bytes, if randomReader is nil crypto/rand.Reader is useds
-func GeneratePrivateKey(randomReader io.Reader) (PrivateKey, error) {
-	if randomReader == nil {
-		randomReader = rand.Reader
-	}
-	_, ed25519PrivateKey, err := ed25519.GenerateKey(randomReader)
-	if err != nil {
-		return PrivateKey{}, err
-	}
-	return Ed25519PrivateKeyFromRawBytes(ed25519PrivateKey)
-}
-
-// Creates an ed25519 key from the raw private key bytes
-func Ed25519PrivateKeyFromRawBytes(privKeyBytes []byte) (PrivateKey, error) {
-	privKeyEd25519 := crypto.PrivKeyEd25519{}
-	if len(privKeyBytes) != len(privKeyEd25519) {
-		return PrivateKey{}, fmt.Errorf("bytes passed have length %v by ed25519 private keys have %v bytes",
-			len(privKeyBytes), len(privKeyEd25519))
-	}
-	err := EnsureEd25519PrivateKeyCorrect(privKeyBytes)
-	if err != nil {
-		return PrivateKey{}, err
-	}
-	copy(privKeyEd25519[:], privKeyBytes)
-	return PrivateKeyFromGoCryptoPrivKey(privKeyEd25519.Wrap())
-}
-
-// Ensures the last 32 bytes of the ed25519 private key is the public key derived from the first 32 private bytes
-func EnsureEd25519PrivateKeyCorrect(candidatePrivateKey ed25519.PrivateKey) error {
-	if len(candidatePrivateKey) != ed25519.PrivateKeySize {
-		return fmt.Errorf("ed25519 key has size %v but %v bytes passed as key", ed25519.PrivateKeySize,
-			len(candidatePrivateKey))
-	}
-	_, derivedPrivateKey, err := ed25519.GenerateKey(bytes.NewBuffer(candidatePrivateKey))
-	if err != nil {
-		return err
-	}
-	if !bytes.Equal(derivedPrivateKey, candidatePrivateKey) {
-		return fmt.Errorf("ed25519 key generated from prefix of %X should equal %X, but is %X",
-			candidatePrivateKey, candidatePrivateKey, derivedPrivateKey)
-	}
-	return nil
-}
-
-func (pk PrivateKey) PublicKey() PublicKey {
-	publicKey, err := PublicKeyFromGoCryptoPubKey(pk.PrivKey.PubKey())
-	if err != nil {
-		// We check this on initialisation to avoid this panic, but returning an error here is ugly and  caching
-		// the public key on PrivateKey on initialisation breaks go-wire. We can do something better with better serialisation
-		panic(fmt.Errorf("error making public key from private key: %v", publicKey))
-	}
-	return publicKey
-}
-
-// Returns a copy of the raw untyped private key bytes
-func (pk PrivateKey) RawBytes() []byte {
-	switch privKey := pk.PrivKey.Unwrap().(type) {
-	case crypto.PrivKeyEd25519:
-		privKeyCopy := crypto.PrivKeyEd25519{}
-		copy(privKeyCopy[:], privKey[:])
-		return privKeyCopy[:]
-	case crypto.PrivKeySecp256k1:
-		privKeyCopy := crypto.PrivKeySecp256k1{}
-		copy(privKeyCopy[:], privKey[:])
-		return privKeyCopy[:]
-	default:
-		return nil
-	}
-}
-
-func (pk PrivateKey) Sign(msg []byte) (Signature, error) {
-	return Signature{Signature: pk.PrivKey.Sign(msg)}, nil
-}
-
-func (pk PrivateKey) MarshalJSON() ([]byte, error) {
-	return pk.PrivKey.MarshalJSON()
-}
-
-func (pk *PrivateKey) UnmarshalJSON(data []byte) error {
-	return pk.PrivKey.UnmarshalJSON(data)
-}
-
-func (pk PrivateKey) MarshalText() ([]byte, error) {
-	return pk.MarshalJSON()
-}
-
-func (pk *PrivateKey) UnmarshalText(text []byte) error {
-	return pk.UnmarshalJSON(text)
-}
-
-// Signature
-
-type Signature struct {
-	crypto.Signature `json:"unwrap"`
-}
-
-func SignatureFromGoCryptoSignature(signature crypto.Signature) Signature {
-	return Signature{Signature: signature}
-}
-
-// Currently this is a stub that reads the raw bytes returned by key_client and returns
-// an ed25519 signature.
-func SignatureFromBytes(bs []byte) (Signature, error) {
-	//TODO: read a typed representation (most likely JSON) and do the right thing here
-	// Only supports ed25519 currently so no switch on signature scheme
-	signatureEd25519 := crypto.SignatureEd25519{}
-	if len(bs) != len(signatureEd25519) {
-		return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes",
-			len(bs), len(signatureEd25519))
-	}
-	copy(signatureEd25519[:], bs)
-	return Signature{
-		Signature: signatureEd25519.Wrap(),
-	}, nil
-}
-
-func (s Signature) GoCryptoSignature() crypto.Signature {
-	return s.Signature
-}
-
-func (s Signature) MarshalJSON() ([]byte, error) {
-	return s.Signature.MarshalJSON()
-}
-
-func (s *Signature) UnmarshalJSON(data []byte) error {
-	return s.Signature.UnmarshalJSON(data)
-}
-
-func (s Signature) MarshalText() ([]byte, error) {
-	return s.MarshalJSON()
-}
-
-func (s *Signature) UnmarshalText(text []byte) error {
-	return s.UnmarshalJSON(text)
-}
diff --git a/account/private_account.go b/account/private_account.go
index 3ca56cd7f0852ed348c08f10b972c23557090790..8f76a5c41c049b8de1761e1ea9c5aca53b34cc96 100644
--- a/account/private_account.go
+++ b/account/private_account.go
@@ -17,24 +17,25 @@ package account
 import (
 	"fmt"
 
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type AddressableSigner interface {
 	Addressable
-	Signer
+	crypto.Signer
 }
 
 type PrivateAccount interface {
 	AddressableSigner
-	PrivateKey() PrivateKey
+	PrivateKey() crypto.PrivateKey
 }
 
 //
 type ConcretePrivateAccount struct {
-	Address    Address
-	PublicKey  PublicKey
-	PrivateKey PrivateKey
+	Address    crypto.Address
+	PublicKey  crypto.PublicKey
+	PrivateKey crypto.PrivateKey
 }
 
 type concretePrivateAccountWrapper struct {
@@ -60,15 +61,15 @@ func AsConcretePrivateAccount(privateAccount PrivateAccount) *ConcretePrivateAcc
 	}
 }
 
-func (cpaw concretePrivateAccountWrapper) Address() Address {
+func (cpaw concretePrivateAccountWrapper) Address() crypto.Address {
 	return cpaw.ConcretePrivateAccount.Address
 }
 
-func (cpaw concretePrivateAccountWrapper) PublicKey() PublicKey {
+func (cpaw concretePrivateAccountWrapper) PublicKey() crypto.PublicKey {
 	return cpaw.ConcretePrivateAccount.PublicKey
 }
 
-func (cpaw concretePrivateAccountWrapper) PrivateKey() PrivateKey {
+func (cpaw concretePrivateAccountWrapper) PrivateKey() crypto.PrivateKey {
 	return cpaw.ConcretePrivateAccount.PrivateKey
 }
 
@@ -82,18 +83,10 @@ func (pa ConcretePrivateAccount) PrivateAccount() PrivateAccount {
 	return concretePrivateAccountWrapper{ConcretePrivateAccount: &pa}
 }
 
-func (pa ConcretePrivateAccount) Sign(msg []byte) (Signature, error) {
+func (pa ConcretePrivateAccount) Sign(msg []byte) (crypto.Signature, error) {
 	return pa.PrivateKey.Sign(msg)
 }
 
-func ChainSign(signer Signer, chainID string, o Signable) (Signature, error) {
-	sig, err := signer.Sign(SignBytes(chainID, o))
-	if err != nil {
-		return Signature{}, err
-	}
-	return sig, nil
-}
-
 func (pa *ConcretePrivateAccount) String() string {
 	return fmt.Sprintf("ConcretePrivateAccount{%s}", pa.Address)
 }
@@ -109,11 +102,11 @@ func SigningAccounts(concretePrivateAccounts []*ConcretePrivateAccount) []Addres
 
 // Generates a new account with private key.
 func GeneratePrivateAccount() (PrivateAccount, error) {
-	privateKey, err := GeneratePrivateKey(nil)
+	privateKey, err := crypto.GeneratePrivateKey(nil, crypto.CurveTypeEd25519)
 	if err != nil {
 		return nil, err
 	}
-	publicKey := privateKey.PublicKey()
+	publicKey := privateKey.GetPublicKey()
 	return ConcretePrivateAccount{
 		Address:    publicKey.Address(),
 		PublicKey:  publicKey,
@@ -123,8 +116,8 @@ func GeneratePrivateAccount() (PrivateAccount, error) {
 
 // Generates a new account with private key from SHA256 hash of a secret
 func GeneratePrivateAccountFromSecret(secret string) PrivateAccount {
-	privateKey := PrivateKeyFromSecret(secret)
-	publicKey := privateKey.PublicKey()
+	privateKey := crypto.PrivateKeyFromSecret(secret, crypto.CurveTypeEd25519)
+	publicKey := privateKey.GetPublicKey()
 	return ConcretePrivateAccount{
 		Address:    publicKey.Address(),
 		PublicKey:  publicKey,
@@ -133,11 +126,11 @@ func GeneratePrivateAccountFromSecret(secret string) PrivateAccount {
 }
 
 func GeneratePrivateAccountFromPrivateKeyBytes(privKeyBytes []byte) (PrivateAccount, error) {
-	privateKey, err := Ed25519PrivateKeyFromRawBytes(privKeyBytes)
+	privateKey, err := crypto.PrivateKeyFromRawBytes(privKeyBytes, crypto.CurveTypeEd25519)
 	if err != nil {
 		return nil, err
 	}
-	publicKey := privateKey.PublicKey()
+	publicKey := privateKey.GetPublicKey()
 	return ConcretePrivateAccount{
 		Address:    publicKey.Address(),
 		PublicKey:  publicKey,
diff --git a/account/state/memory_state.go b/account/state/memory_state.go
index 35f1ad696e5e4820c751f973e1148a120980caed..368c4fa3bf849a0c4d5eaf13f7ac3ea73d0a2719 100644
--- a/account/state/memory_state.go
+++ b/account/state/memory_state.go
@@ -5,11 +5,12 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 )
 
 type MemoryState struct {
-	Accounts map[acm.Address]acm.Account
-	Storage  map[acm.Address]map[binary.Word256]binary.Word256
+	Accounts map[crypto.Address]acm.Account
+	Storage  map[crypto.Address]map[binary.Word256]binary.Word256
 }
 
 var _ IterableWriter = &MemoryState{}
@@ -17,12 +18,12 @@ var _ IterableWriter = &MemoryState{}
 // Get an in-memory state Iterable
 func NewMemoryState() *MemoryState {
 	return &MemoryState{
-		Accounts: make(map[acm.Address]acm.Account),
-		Storage:  make(map[acm.Address]map[binary.Word256]binary.Word256),
+		Accounts: make(map[crypto.Address]acm.Account),
+		Storage:  make(map[crypto.Address]map[binary.Word256]binary.Word256),
 	}
 }
 
-func (ms *MemoryState) GetAccount(address acm.Address) (acm.Account, error) {
+func (ms *MemoryState) GetAccount(address crypto.Address) (acm.Account, error) {
 	return ms.Accounts[address], nil
 }
 
@@ -34,12 +35,12 @@ func (ms *MemoryState) UpdateAccount(updatedAccount acm.Account) error {
 	return nil
 }
 
-func (ms *MemoryState) RemoveAccount(address acm.Address) error {
+func (ms *MemoryState) RemoveAccount(address crypto.Address) error {
 	delete(ms.Accounts, address)
 	return nil
 }
 
-func (ms *MemoryState) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) {
+func (ms *MemoryState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	storage, ok := ms.Storage[address]
 	if !ok {
 		return binary.Zero256, fmt.Errorf("could not find storage for account %s", address)
@@ -51,7 +52,7 @@ func (ms *MemoryState) GetStorage(address acm.Address, key binary.Word256) (bina
 	return value, nil
 }
 
-func (ms *MemoryState) SetStorage(address acm.Address, key, value binary.Word256) error {
+func (ms *MemoryState) SetStorage(address crypto.Address, key, value binary.Word256) error {
 	storage, ok := ms.Storage[address]
 	if !ok {
 		storage = make(map[binary.Word256]binary.Word256)
@@ -70,7 +71,7 @@ func (ms *MemoryState) IterateAccounts(consumer func(acm.Account) (stop bool)) (
 	return false, nil
 }
 
-func (ms *MemoryState) IterateStorage(address acm.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
+func (ms *MemoryState) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
 	for key, value := range ms.Storage[address] {
 		if consumer(key, value) {
 			return true, nil
diff --git a/account/state/state.go b/account/state/state.go
index d175f6e8e8742ea649814a3ee24cfa2152820311..645462abde6c325fdf9fe7c547683eb258d34dd5 100644
--- a/account/state/state.go
+++ b/account/state/state.go
@@ -3,12 +3,13 @@ package state
 import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 )
 
 type AccountGetter interface {
 	// Get an account by its address return nil if it does not exist (which should not be an error)
-	GetAccount(address acm.Address) (acm.Account, error)
+	GetAccount(address crypto.Address) (acm.Account, error)
 }
 
 type AccountIterable interface {
@@ -23,25 +24,25 @@ type AccountUpdater interface {
 	// if it does not exist
 	UpdateAccount(updatedAccount acm.Account) error
 	// Remove the account at address
-	RemoveAccount(address acm.Address) error
+	RemoveAccount(address crypto.Address) error
 }
 
 type StorageGetter interface {
 	// Retrieve a 32-byte value stored at key for the account at address, return Zero256 if key does not exist but
 	// error if address does not
-	GetStorage(address acm.Address, key binary.Word256) (value binary.Word256, err error)
+	GetStorage(address crypto.Address, key binary.Word256) (value binary.Word256, err error)
 }
 
 type StorageSetter interface {
 	// Store a 32-byte value at key for the account at address, setting to Zero256 removes the key
-	SetStorage(address acm.Address, key, value binary.Word256) error
+	SetStorage(address crypto.Address, key, value binary.Word256) error
 }
 
 type StorageIterable interface {
 	// Iterates through the storage of account ad address calling the passed function once per account,
 	// if the iterator function returns true the iteration breaks and returns true to indicate it iteration
 	// was escaped
-	IterateStorage(address acm.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error)
+	IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error)
 }
 
 // Compositions
@@ -74,7 +75,7 @@ type IterableWriter interface {
 	StorageIterable
 }
 
-func GetMutableAccount(getter AccountGetter, address acm.Address) (acm.MutableAccount, error) {
+func GetMutableAccount(getter AccountGetter, address crypto.Address) (acm.MutableAccount, error) {
 	acc, err := getter.GetAccount(address)
 	if err != nil {
 		return nil, err
diff --git a/account/state/state_cache.go b/account/state/state_cache.go
index 81b0dcd2c24469968be0db44f3d82b4ec7d9e559..75dd70b1cf33be132d2685990a2ade2d302fb466 100644
--- a/account/state/state_cache.go
+++ b/account/state/state_cache.go
@@ -21,6 +21,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 )
 
 type Cache interface {
@@ -34,7 +35,7 @@ type stateCache struct {
 	sync.RWMutex
 	name     string
 	backend  Reader
-	accounts map[acm.Address]*accountInfo
+	accounts map[crypto.Address]*accountInfo
 }
 
 type accountInfo struct {
@@ -52,7 +53,7 @@ type CacheOption func(*stateCache)
 func NewCache(backend Reader, options ...CacheOption) Cache {
 	cache := &stateCache{
 		backend:  backend,
-		accounts: make(map[acm.Address]*accountInfo),
+		accounts: make(map[crypto.Address]*accountInfo),
 	}
 	for _, option := range options {
 		option(cache)
@@ -66,7 +67,7 @@ func Name(name string) CacheOption {
 	}
 }
 
-func (cache *stateCache) GetAccount(address acm.Address) (acm.Account, error) {
+func (cache *stateCache) GetAccount(address crypto.Address) (acm.Account, error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return nil, err
@@ -94,7 +95,7 @@ func (cache *stateCache) UpdateAccount(account acm.Account) error {
 	return nil
 }
 
-func (cache *stateCache) RemoveAccount(address acm.Address) error {
+func (cache *stateCache) RemoveAccount(address crypto.Address) error {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return err
@@ -122,7 +123,7 @@ func (cache *stateCache) IterateCachedAccount(consumer func(acm.Account) (stop b
 	return false, nil
 }
 
-func (cache *stateCache) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) {
+func (cache *stateCache) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
 		return binary.Zero256, err
@@ -148,7 +149,7 @@ func (cache *stateCache) GetStorage(address acm.Address, key binary.Word256) (bi
 }
 
 // NOTE: Set value to zero to remove.
-func (cache *stateCache) SetStorage(address acm.Address, key binary.Word256, value binary.Word256) error {
+func (cache *stateCache) SetStorage(address crypto.Address, key binary.Word256, value binary.Word256) error {
 	accInfo, err := cache.get(address)
 	accInfo.Lock()
 	defer accInfo.Unlock()
@@ -164,7 +165,7 @@ func (cache *stateCache) SetStorage(address acm.Address, key binary.Word256, val
 }
 
 // Iterates over all cached storage items first in cache and then in backend until consumer returns true for 'stop'
-func (cache *stateCache) IterateCachedStorage(address acm.Address,
+func (cache *stateCache) IterateCachedStorage(address crypto.Address,
 	consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
 	accInfo, err := cache.get(address)
 	if err != nil {
@@ -187,7 +188,7 @@ func (cache *stateCache) IterateCachedStorage(address acm.Address,
 func (cache *stateCache) Sync(state Writer) error {
 	cache.Lock()
 	defer cache.Unlock()
-	var addresses acm.Addresses
+	var addresses crypto.Addresses
 	for address := range cache.accounts {
 		addresses = append(addresses, address)
 	}
@@ -232,7 +233,7 @@ func (cache *stateCache) Reset(backend Iterable) {
 	cache.Lock()
 	defer cache.Unlock()
 	cache.backend = backend
-	cache.accounts = make(map[acm.Address]*accountInfo, len(cache.accounts))
+	cache.accounts = make(map[crypto.Address]*accountInfo, len(cache.accounts))
 }
 
 // Syncs the Cache and Resets it to use as the backend Reader
@@ -253,7 +254,7 @@ func (cache *stateCache) String() string {
 }
 
 // Get the cache accountInfo item creating it if necessary
-func (cache *stateCache) get(address acm.Address) (*accountInfo, error) {
+func (cache *stateCache) get(address crypto.Address) (*accountInfo, error) {
 	cache.RLock()
 	accInfo := cache.accounts[address]
 	cache.RUnlock()
diff --git a/account/state/state_cache_test.go b/account/state/state_cache_test.go
index 76ffee5cb17ef90844103853d4a2669cca1f366d..92171155cf68cf2d796a83159c6d1fcb0ee14bb9 100644
--- a/account/state/state_cache_test.go
+++ b/account/state/state_cache_test.go
@@ -7,6 +7,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/evm/asm"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
@@ -305,7 +306,7 @@ func testAccounts() *MemoryState {
 	return cache
 }
 
-func addressOf(secret string) acm.Address {
+func addressOf(secret string) crypto.Address {
 	return acm.NewConcreteAccountFromSecret(secret).Address
 }
 
diff --git a/account/validator.go b/account/validator.go
index 5271a2f4a01cdba71280175ff4fde479fb80576e..017b1eb2a180036f22665aaac2b8ff5fd6750ba6 100644
--- a/account/validator.go
+++ b/account/validator.go
@@ -2,6 +2,8 @@ package account
 
 import (
 	"encoding/json"
+
+	"github.com/hyperledger/burrow/crypto"
 )
 
 type Validator interface {
@@ -15,8 +17,8 @@ type Validator interface {
 
 // Neither abci_types or tm_types has quite the representation we want
 type ConcreteValidator struct {
-	Address   Address
-	PublicKey PublicKey
+	Address   crypto.Address
+	PublicKey crypto.PublicKey
 	Power     uint64
 }
 
@@ -48,11 +50,11 @@ func AsConcreteValidator(validator Validator) *ConcreteValidator {
 	}
 }
 
-func (cvw concreteValidatorWrapper) Address() Address {
+func (cvw concreteValidatorWrapper) Address() crypto.Address {
 	return cvw.ConcreteValidator.Address
 }
 
-func (cvw concreteValidatorWrapper) PublicKey() PublicKey {
+func (cvw concreteValidatorWrapper) PublicKey() crypto.PublicKey {
 	return cvw.ConcreteValidator.PublicKey
 }
 
diff --git a/client/methods/call.go b/client/methods/call.go
index c613ff489f089c14d0a8286127ad47c2abecea3b..38271439ae27955983272440f640df28c6eeebde 100644
--- a/client/methods/call.go
+++ b/client/methods/call.go
@@ -29,7 +29,10 @@ func Call(do *client.Do) error {
 	if err != nil {
 		return fmt.Errorf("Could not generate logging config from Do: %s", err)
 	}
-	burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger)
+	burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger)
+	if err != nil {
+		return fmt.Errorf("Could not create remote key client: %s", err)
+	}
 	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
 	// form the call transaction
 	callTransaction, err := rpc.Call(burrowNodeClient, burrowKeyClient,
diff --git a/client/methods/send.go b/client/methods/send.go
index b9736d5065816f1ec43a69c9479288c99a0cffcf..e04771e185b358a22c0e8fcb53b99adb47504bc9 100644
--- a/client/methods/send.go
+++ b/client/methods/send.go
@@ -29,7 +29,10 @@ func Send(do *client.Do) error {
 	if err != nil {
 		return fmt.Errorf("Could not generate logging config from Do: %s", err)
 	}
-	burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger)
+	burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger)
+	if err != nil {
+		return fmt.Errorf("Could not create remote key client: %s", err)
+	}
 	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
 	// form the send transaction
 	sendTransaction, err := rpc.Send(burrowNodeClient, burrowKeyClient,
diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go
index 0fb53896ffb2284a7e9d754d75577afae03627b8..c683cc4ee3ed6b4dc1e702adc34387ffd789e72b 100644
--- a/client/mock/client_mock.go
+++ b/client/mock/client_mock.go
@@ -17,10 +17,11 @@ package mock
 import (
 	acm "github.com/hyperledger/burrow/account"
 	. "github.com/hyperledger/burrow/client"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/txs"
-	"github.com/tendermint/go-crypto"
+	tm_crypto "github.com/tendermint/go-crypto"
 )
 
 var _ NodeClient = (*MockNodeClient)(nil)
@@ -48,7 +49,7 @@ func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketC
 	return nil, nil
 }
 
-func (mock *MockNodeClient) GetAccount(address acm.Address) (acm.Account, error) {
+func (mock *MockNodeClient) GetAccount(address crypto.Address) (acm.Account, error) {
 	// make zero account
 	return acm.FromAddressable(acm.GeneratePrivateAccountFromSecret("mock-node-client-account")), nil
 }
@@ -63,14 +64,14 @@ func (mock *MockNodeClient) Status() (ChainId []byte, ValidatorPublicKey []byte,
 	// fill return values
 	ChainId = make([]byte, 64)
 	LatestBlockHash = make([]byte, 64)
-	ValidatorPublicKey = crypto.PubKeyEd25519{}.Wrap().Bytes()
+	ValidatorPublicKey = tm_crypto.PubKeyEd25519{}.Wrap().Bytes()
 	BlockHeight = 0
 	LatestBlockTime = 0
 	return
 }
 
 // QueryContract executes the contract code at address with the given data
-func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress acm.Address,
+func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address,
 	data []byte) (ret []byte, gasUsed uint64, err error) {
 
 	// return zero
@@ -79,18 +80,18 @@ func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress acm.Addre
 }
 
 // QueryContractCode executes the contract code at address with the given data but with provided code
-func (mock *MockNodeClient) QueryContractCode(address acm.Address, code,
+func (mock *MockNodeClient) QueryContractCode(address crypto.Address, code,
 	data []byte) (ret []byte, gasUsed uint64, err error) {
 	// return zero
 	ret = make([]byte, 0)
 	return
 }
 
-func (mock *MockNodeClient) DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error) {
+func (mock *MockNodeClient) DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) {
 	return
 }
 
-func (mock *MockNodeClient) GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error) {
+func (mock *MockNodeClient) GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) {
 	return
 }
 
diff --git a/client/node_client.go b/client/node_client.go
index 6e19231a2405c1edced4b45d713a968c61851a9c..c98ff55086e0dfb2fedab79e6916fce0b0dce167 100644
--- a/client/node_client.go
+++ b/client/node_client.go
@@ -18,6 +18,7 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/rpc"
 	tendermint_client "github.com/hyperledger/burrow/rpc/tm/client"
@@ -31,12 +32,12 @@ type NodeClient interface {
 
 	Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
 		LatestBlockHeight uint64, LatestBlockTime int64, err error)
-	GetAccount(address acm.Address) (acm.Account, error)
-	QueryContract(callerAddress, calleeAddress acm.Address, data []byte) (ret []byte, gasUsed uint64, err error)
-	QueryContractCode(address acm.Address, code, data []byte) (ret []byte, gasUsed uint64, err error)
+	GetAccount(address crypto.Address) (acm.Account, error)
+	QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error)
+	QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error)
 
-	DumpStorage(address acm.Address) (storage *rpc.ResultDumpStorage, err error)
-	GetName(name string) (owner acm.Address, data string, expirationBlock uint64, err error)
+	DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error)
+	GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error)
 	ListValidators() (blockHeight uint64, bondedValidators, unbondingValidators []acm.Validator, err error)
 
 	// Logging context for this NodeClient
@@ -47,7 +48,7 @@ type NodeWebsocketClient interface {
 	Subscribe(eventId string) error
 	Unsubscribe(eventId string) error
 
-	WaitForConfirmation(tx txs.Tx, chainId string, inputAddr acm.Address) (chan Confirmation, error)
+	WaitForConfirmation(tx txs.Tx, chainId string, inputAddr crypto.Address) (chan Confirmation, error)
 	Close()
 }
 
@@ -133,7 +134,7 @@ func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, Validato
 
 	// unwrap return results
 	GenesisHash = res.GenesisHash
-	ValidatorPublicKey = res.PubKey.Bytes()
+	ValidatorPublicKey = res.PubKey.RawBytes()
 	LatestBlockHash = res.LatestBlockHash
 	LatestBlockHeight = res.LatestBlockHeight
 	LatestBlockTime = res.LatestBlockTime
@@ -158,7 +159,7 @@ func (burrowNodeClient *burrowNodeClient) ChainId() (ChainName, ChainId string,
 
 // QueryContract executes the contract code at address with the given data
 // NOTE: there is no check on the caller;
-func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress acm.Address,
+func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address,
 	data []byte) (ret []byte, gasUsed uint64, err error) {
 
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
@@ -172,7 +173,7 @@ func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAdd
 }
 
 // QueryContractCode executes the contract code at address with the given data but with provided code
-func (burrowNodeClient *burrowNodeClient) QueryContractCode(address acm.Address, code,
+func (burrowNodeClient *burrowNodeClient) QueryContractCode(address crypto.Address, code,
 	data []byte) (ret []byte, gasUsed uint64, err error) {
 
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
@@ -188,7 +189,7 @@ func (burrowNodeClient *burrowNodeClient) QueryContractCode(address acm.Address,
 }
 
 // GetAccount returns a copy of the account
-func (burrowNodeClient *burrowNodeClient) GetAccount(address acm.Address) (acm.Account, error) {
+func (burrowNodeClient *burrowNodeClient) GetAccount(address crypto.Address) (acm.Account, error) {
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	account, err := tendermint_client.GetAccount(client, address)
 	if err != nil {
@@ -205,7 +206,7 @@ func (burrowNodeClient *burrowNodeClient) GetAccount(address acm.Address) (acm.A
 }
 
 // DumpStorage returns the full storage for an acm.
-func (burrowNodeClient *burrowNodeClient) DumpStorage(address acm.Address) (*rpc.ResultDumpStorage, error) {
+func (burrowNodeClient *burrowNodeClient) DumpStorage(address crypto.Address) (*rpc.ResultDumpStorage, error) {
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
 	resultStorage, err := tendermint_client.DumpStorage(client, address)
 	if err != nil {
@@ -218,7 +219,7 @@ func (burrowNodeClient *burrowNodeClient) DumpStorage(address acm.Address) (*rpc
 //--------------------------------------------------------------------------------------------
 // Name registry
 
-func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner acm.Address, data string,
+func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner crypto.Address, data string,
 	expirationBlock uint64, err error) {
 
 	client := rpcclient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
@@ -226,7 +227,7 @@ func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner acm.Addres
 	if err != nil {
 		err = fmt.Errorf("error connecting to node (%s) to get name registrar entry for name (%s)",
 			burrowNodeClient.broadcastRPC, name)
-		return acm.ZeroAddress, "", 0, err
+		return crypto.ZeroAddress, "", 0, err
 	}
 	// unwrap return results
 	owner = entryResult.Owner
diff --git a/client/rpc/client.go b/client/rpc/client.go
index 3a76948c2638df2e4589c5e5188dc8bf75635c7d..b2afaec4a55ba75d1ff2bf2ec94f323459ca040a 100644
--- a/client/rpc/client.go
+++ b/client/rpc/client.go
@@ -19,9 +19,9 @@ import (
 	"fmt"
 	"strconv"
 
+	"github.com/hyperledger/burrow/crypto"
 	ptypes "github.com/hyperledger/burrow/permission"
 
-	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/client"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/permission/snatives"
@@ -60,7 +60,7 @@ func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 		return nil, err
 	}
 
-	var toAddress *acm.Address
+	var toAddress *crypto.Address
 
 	if toAddr != "" {
 		address, err := addressFromHexString(toAddr)
@@ -121,7 +121,7 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 
 	// Try and set each PermArg field for which a string has been provided we'll validate afterwards
 	if target != "" {
-		address, err := acm.AddressFromHexString(target)
+		address, err := crypto.AddressFromHexString(target)
 		if err != nil {
 			return nil, err
 		}
@@ -238,7 +238,7 @@ type TxResult struct {
 	Hash      []byte // all txs get a hash
 
 	// only CallTx
-	Address   *acm.Address // only for new contracts
+	Address   *crypto.Address // only for new contracts
 	Return    []byte
 	Exception string
 
@@ -250,7 +250,7 @@ type TxResult struct {
 func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient keys.KeyClient, tx txs.Tx, sign,
 	broadcast, wait bool) (txResult *TxResult, err error) {
 
-	var inputAddr acm.Address
+	var inputAddr crypto.Address
 	if sign {
 		inputAddr, tx, err = signTx(keyClient, chainID, tx)
 		if err != nil {
@@ -312,7 +312,7 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 		// the benefit is that the we don't need to trust the chain node
 		if tx_, ok := tx.(*txs.CallTx); ok {
 			if tx_.Address == nil {
-				address := acm.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence)
+				address := crypto.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence)
 				txResult.Address = &address
 			}
 		}
@@ -320,10 +320,10 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 	return
 }
 
-func addressFromHexString(addrString string) (acm.Address, error) {
+func addressFromHexString(addrString string) (crypto.Address, error) {
 	addrBytes, err := hex.DecodeString(addrString)
 	if err != nil {
-		return acm.Address{}, err
+		return crypto.Address{}, err
 	}
-	return acm.AddressFromBytes(addrBytes)
+	return crypto.AddressFromBytes(addrBytes)
 }
diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go
index 914ba28f6387d87305d11c694c9f96c416092253..b904a4f0901bc2b53f319804a6834a13df85e118 100644
--- a/client/rpc/client_util.go
+++ b/client/rpc/client_util.go
@@ -19,8 +19,8 @@ import (
 	"fmt"
 	"strconv"
 
-	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/client"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/txs"
 )
@@ -30,8 +30,8 @@ import (
 
 // tx has either one input or we default to the first one (ie for send/bond)
 // TODO: better support for multisig and bonding
-func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (acm.Address, txs.Tx, error) {
-	signBytes := acm.SignBytes(chainID, tx_)
+func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (crypto.Address, txs.Tx, error) {
+	signBytes := crypto.SignBytes(chainID, tx_)
 	var err error
 	switch tx := tx_.(type) {
 	case *txs.SendTx:
@@ -71,12 +71,12 @@ func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) (acm.Address,
 		return signAddress, tx, err
 
 	default:
-		return acm.ZeroAddress, nil, fmt.Errorf("unknown transaction type for signTx: %#v", tx_)
+		return crypto.ZeroAddress, nil, fmt.Errorf("unknown transaction type for signTx: %#v", tx_)
 	}
 }
 
 func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS,
-	sequenceS string) (pub acm.PublicKey, amt uint64, sequence uint64, err error) {
+	sequenceS string) (pub crypto.PublicKey, amt uint64, sequence uint64, err error) {
 
 	if amtS == "" {
 		err = fmt.Errorf("input must specify an amount with the --amt flag")
@@ -99,7 +99,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			err = fmt.Errorf("pubkey is bad hex: %v", err)
 			return
 		}
-		pub, err = acm.PublicKeyFromBytes(pubKeyBytes)
+		pub, err = crypto.PublicKeyFromBytes(pubKeyBytes, crypto.CurveTypeEd25519)
 		if err != nil {
 			return
 		}
@@ -110,7 +110,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			err = fmt.Errorf("Bad hex string for address (%s): %v", addr, err)
 			return
 		}
-		address, err2 := acm.AddressFromBytes(addressBytes)
+		address, err2 := crypto.AddressFromBytes(addressBytes)
 		if err2 != nil {
 			err = fmt.Errorf("Could not convert bytes (%X) to address: %v", addressBytes, err2)
 		}
@@ -121,7 +121,7 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 		}
 	}
 
-	var address acm.Address
+	var address crypto.Address
 	address = pub.Address()
 
 	amt, err = strconv.ParseUint(amtS, 10, 64)
diff --git a/client/websocket_client.go b/client/websocket_client.go
index fe08dde89d912394e422cccd9e1f33f068f938a0..1841cefc4c36de8c026533c133c3551c6f1c5535 100644
--- a/client/websocket_client.go
+++ b/client/websocket_client.go
@@ -21,7 +21,7 @@ import (
 
 	"encoding/json"
 
-	"github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	exe_events "github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
@@ -69,7 +69,7 @@ func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Unsubscribe(subscrip
 // Returns a channel that will receive a confirmation with a result or the exception that
 // has been confirmed; or an error is returned and the confirmation channel is nil.
 func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string,
-	inputAddr account.Address) (chan Confirmation, error) {
+	inputAddr crypto.Address) (chan Confirmation, error) {
 
 	// Setup the confirmation channel to be returned
 	confirmationChannel := make(chan Confirmation, 1)
diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go
index 97c64432f120452f7db6e5c8004081e235687f7c..a964e2f9eb86b330eb34327ccfb8d31bbdc43c1b 100644
--- a/cmd/burrow/commands/configure.go
+++ b/cmd/burrow/commands/configure.go
@@ -12,7 +12,6 @@ import (
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/genesis/spec"
 	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/keys/mock"
 	"github.com/hyperledger/burrow/logging"
 	logging_config "github.com/hyperledger/burrow/logging/config"
 	"github.com/hyperledger/burrow/logging/config/presets"
@@ -27,8 +26,8 @@ func Configure(output Output) func(cmd *cli.Cmd) {
 		jsonOutOpt := cmd.BoolOpt("j json", false, "Emit config in JSON rather than TOML "+
 			"suitable for further processing")
 
-		keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys URL, default: %s",
-			keys.DefaultKeysConfig().URL))
+		keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys GRPC address, default: %s",
+			keys.DefaultKeysConfig().RemoteAddress))
 
 		configOpt := cmd.StringOpt("c base-config", "", "Use the a specified burrow config file as a base")
 
@@ -85,7 +84,7 @@ func Configure(output Output) func(cmd *cli.Cmd) {
 			}
 
 			if *keysUrlOpt != "" {
-				conf.Keys.URL = *keysUrlOpt
+				conf.Keys.RemoteAddress = *keysUrlOpt
 			}
 
 			// Genesis Spec
@@ -95,14 +94,22 @@ func Configure(output Output) func(cmd *cli.Cmd) {
 				if err != nil {
 					output.Fatalf("Could not read GenesisSpec: %v", err)
 				}
+				keyStore := keys.NewKeyStore(conf.Keys.KeysDirectory)
 				if *generateKeysOpt != "" {
-					keyClient := mock.NewKeyClient()
+					keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger())
 					conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient)
 					if err != nil {
 						output.Fatalf("Could not generate GenesisDoc from GenesisSpec using MockKeyClient: %v", err)
 					}
 
-					pkg := deployment.Package{Keys: keyClient.Keys()}
+					allKeys, err := keyStore.AllKeys()
+					if err != nil {
+						output.Fatalf("could get all keys: %v", err)
+					}
+					pkg := deployment.Package{Keys: allKeys}
+					if err != nil {
+						output.Fatalf("Could not dump keys: %v", err)
+					}
 					secretKeysString, err := pkg.Dump(*keysTemplateOpt)
 					if err != nil {
 						output.Fatalf("Could not dump keys: %v", err)
@@ -112,8 +119,18 @@ func Configure(output Output) func(cmd *cli.Cmd) {
 						output.Fatalf("Could not write secret keys: %v", err)
 					}
 				} else {
-					conf.GenesisDoc, err = genesisSpec.GenesisDoc(keys.NewKeyClient(conf.Keys.URL, logging.NewNoopLogger()))
+					var keyClient keys.KeyClient
+					if conf.Keys.RemoteAddress != "" {
+						keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logging.NewNoopLogger())
+						if err != nil {
+							output.Fatalf("Could not create remote key client: %v", err)
+						}
+					} else {
+						keyClient = keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger())
+					}
+					conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient)
 				}
+
 				if err != nil {
 					output.Fatalf("could not realise GenesisSpec: %v", err)
 				}
diff --git a/cmd/burrow/commands/keys.go b/cmd/burrow/commands/keys.go
new file mode 100644
index 0000000000000000000000000000000000000000..10b3c4fe240425a8b1fb8d48252af480befe306e
--- /dev/null
+++ b/cmd/burrow/commands/keys.go
@@ -0,0 +1,319 @@
+package commands
+
+import (
+	"context"
+	"encoding/hex"
+	"fmt"
+	"os"
+
+	"time"
+
+	"io/ioutil"
+
+	"github.com/howeyc/gopass"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/keys/pbkeys"
+	"github.com/jawher/mow.cli"
+	"google.golang.org/grpc"
+)
+
+func Keys(output Output) func(cmd *cli.Cmd) {
+	return func(cmd *cli.Cmd) {
+		keysHost := cmd.String(cli.StringOpt{
+			Name:   "host",
+			Desc:   "set the host for talking to the key daemon",
+			Value:  keys.DefaultHost,
+			EnvVar: "MONAX_KEYS_HOST",
+		})
+
+		keysPort := cmd.String(cli.StringOpt{
+			Name:   "host",
+			Desc:   "set the port for key daemon",
+			Value:  keys.DefaultPort,
+			EnvVar: "MONAX_KEYS_PORT",
+		})
+
+		grpcKeysClient := func(output Output) pbkeys.KeysClient {
+			var opts []grpc.DialOption
+			opts = append(opts, grpc.WithInsecure())
+			conn, err := grpc.Dial(*keysHost+":"+*keysPort, opts...)
+			if err != nil {
+				output.Fatalf("Failed to connect to grpc server: %v", err)
+			}
+			return pbkeys.NewKeysClient(conn)
+		}
+
+		cmd.Command("server", "run keys server", func(cmd *cli.Cmd) {
+			keysDir := cmd.StringOpt("dir", keys.DefaultKeysDir, "specify the location of the directory containing key files")
+
+			cmd.Action = func() {
+				err := keys.StartStandAloneServer(*keysDir, *keysHost, *keysPort)
+				if err != nil {
+					output.Fatalf("Failed to start server: %v", err)
+				}
+			}
+		})
+
+		cmd.Command("gen", "Generates a key using (insert crypto pkgs used)", func(cmd *cli.Cmd) {
+			noPassword := cmd.BoolOpt("n no-password", false, "don't use a password for this key")
+
+			keyType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum),  'ed25519' (tendermint)")
+
+			keyName := cmd.StringOpt("name", "", "name of key to use")
+
+			cmd.Action = func() {
+				curve, err := crypto.CurveTypeFromString(*keyType)
+				if err != nil {
+					output.Fatalf("Unrecognised curve type %v", *keyType)
+				}
+
+				var password string
+				if !*noPassword {
+					fmt.Printf("Enter Password:")
+					pwd, err := gopass.GetPasswdMasked()
+					if err != nil {
+						os.Exit(1)
+					}
+					password = string(pwd)
+				}
+
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Passphrase: password, Curvetype: curve.String(), Keyname: *keyName})
+				if err != nil {
+					output.Fatalf("failed to generate key: %v", err)
+				}
+
+				fmt.Printf("%v\n", resp.GetAddress())
+			}
+		})
+
+		cmd.Command("hash", "hash <some data>", func(cmd *cli.Cmd) {
+			hashType := cmd.StringOpt("t type", keys.DefaultHashType, "specify the hash function to use")
+
+			hexByte := cmd.BoolOpt("hex", false, "the input should be hex decoded to bytes first")
+
+			msg := cmd.StringArg("MSG", "", "message to hash")
+
+			cmd.Action = func() {
+				var message []byte
+				var err error
+				if *hexByte {
+					message, err = hex.DecodeString(*msg)
+					if err != nil {
+						output.Fatalf("failed to hex decode message: %v", err)
+					}
+				} else {
+					message = []byte(*msg)
+				}
+
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: *hashType, Message: message})
+				if err != nil {
+					output.Fatalf("failed to get public key: %v", err)
+				}
+
+				fmt.Printf("%v\n", resp.GetHash())
+			}
+		})
+
+		cmd.Command("export", "Export a key to tendermint format", func(cmd *cli.Cmd) {
+			keyName := cmd.StringOpt("name", "", "name of key to use")
+			keyAddr := cmd.StringOpt("addr", "", "address of key to use")
+			passphrase := cmd.StringOpt("passphrase", "", "passphrase for encrypted key")
+
+			cmd.Action = func() {
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.Export(ctx, &pbkeys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr})
+				if err != nil {
+					output.Fatalf("failed to export key: %v", err)
+				}
+
+				fmt.Printf("%s\n", resp.GetExport())
+			}
+		})
+
+		cmd.Command("import", "import <priv key> | /path/to/keyfile | <key json>", func(cmd *cli.Cmd) {
+			curveType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum),  'ed25519' (tendermint)")
+			noPassword := cmd.BoolOpt("n no-password", false, "don't use a password for this key")
+			key := cmd.StringArg("KEY", "", "private key, filename, or raw json")
+
+			cmd.Action = func() {
+				var password string
+				if !*noPassword {
+					fmt.Printf("Enter Password:")
+					pwd, err := gopass.GetPasswdMasked()
+					if err != nil {
+						os.Exit(1)
+					}
+					password = string(pwd)
+				}
+
+				var privKeyBytes []byte
+				fileContents, err := ioutil.ReadFile(*key)
+				if err == nil {
+					*key = string(fileContents)
+				}
+
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+
+				if (*key)[:1] == "{" {
+					resp, err := c.ImportJSON(ctx, &pbkeys.ImportJSONRequest{JSON: *key})
+					if err != nil {
+						output.Fatalf("failed to import json key: %v", err)
+					}
+
+					fmt.Printf("%s\n", resp.GetAddress())
+				} else {
+					privKeyBytes, err = hex.DecodeString(*key)
+					if err != nil {
+						output.Fatalf("failed to hex decode key: %s", *key)
+					}
+					resp, err := c.Import(ctx, &pbkeys.ImportRequest{Passphrase: password, Keybytes: privKeyBytes, Curvetype: *curveType})
+					if err != nil {
+						output.Fatalf("failed to import json key: %v", err)
+					}
+
+					fmt.Printf("%s\n", resp.GetAddress())
+
+				}
+			}
+		})
+
+		cmd.Command("pub", "public key", func(cmd *cli.Cmd) {
+			name := cmd.StringOpt("name", "", "name of key to use")
+			addr := cmd.StringOpt("addr", "", "address of key to use")
+
+			cmd.Action = func() {
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Name: *name, Address: *addr})
+				if err != nil {
+					output.Fatalf("failed to get public key: %v", err)
+				}
+
+				fmt.Printf("%X\n", resp.GetPub())
+			}
+		})
+
+		cmd.Command("sign", "sign <some data>", func(cmd *cli.Cmd) {
+			name := cmd.StringOpt("name", "", "name of key to use")
+			addr := cmd.StringOpt("addr", "", "address of key to use")
+			msg := cmd.StringArg("MSG", "", "message to sign")
+			passphrase := cmd.StringOpt("passphrase", "", "passphrase for encrypted key")
+
+			cmd.Action = func() {
+				message, err := hex.DecodeString(*msg)
+				if err != nil {
+					output.Fatalf("failed to hex decode message: %v", err)
+				}
+
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message})
+				if err != nil {
+					output.Fatalf("failed to get public key: %v", err)
+				}
+				fmt.Printf("%X\n", resp.GetSignature())
+			}
+		})
+
+		cmd.Command("verify", "verify <some data> <sig> <pubkey>", func(cmd *cli.Cmd) {
+			curveType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum),  'ed25519' (tendermint)")
+
+			msg := cmd.StringArg("MSG", "", "hash/message to check")
+			sig := cmd.StringArg("SIG", "", "signature")
+			pub := cmd.StringArg("PUBLIC", "", "public key")
+
+			cmd.Action = func() {
+				message, err := hex.DecodeString(*msg)
+				if err != nil {
+					output.Fatalf("failed to hex decode message: %v", err)
+				}
+
+				signature, err := hex.DecodeString(*sig)
+				if err != nil {
+					output.Fatalf("failed to hex decode signature: %v", err)
+				}
+
+				publickey, err := hex.DecodeString(*pub)
+				if err != nil {
+					output.Fatalf("failed to hex decode publickey: %v", err)
+				}
+
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				_, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Message: message})
+				if err != nil {
+					output.Fatalf("failed to verify: %v", err)
+				}
+				output.Printf("true\n")
+			}
+		})
+
+		cmd.Command("name", "add key name to addr", func(cmd *cli.Cmd) {
+			keyname := cmd.StringArg("NAME", "", "name of key to use")
+			addr := cmd.StringArg("ADDR", "", "address of key to use")
+
+			cmd.Action = func() {
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				_, err := c.AddName(ctx, &pbkeys.AddNameRequest{Keyname: *keyname, Address: *addr})
+				if err != nil {
+					output.Fatalf("failed to add name to addr: %v", err)
+				}
+			}
+		})
+
+		cmd.Command("list", "list key names", func(cmd *cli.Cmd) {
+			name := cmd.StringOpt("name", "", "name of key to use")
+
+			cmd.Action = func() {
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				resp, err := c.List(ctx, &pbkeys.Name{*name})
+				if err != nil {
+					output.Fatalf("failed to list key names: %v", err)
+				}
+				if *name != "" {
+					for _, k := range resp.Key {
+						if k.Keyname == *name {
+							output.Printf("%s\n", k.Address)
+						}
+					}
+				} else {
+					for _, k := range resp.Key {
+						fmt.Printf("%v\n", k)
+					}
+				}
+			}
+		})
+
+		cmd.Command("rm", "rm key name", func(cmd *cli.Cmd) {
+			name := cmd.StringArg("NAME", "", "key to remove")
+
+			cmd.Action = func() {
+				c := grpcKeysClient(output)
+				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+				defer cancel()
+				_, err := c.RemoveName(ctx, &pbkeys.Name{*name})
+				if err != nil {
+					output.Fatalf("failed to remove key: %v", err)
+				}
+			}
+		})
+	}
+}
diff --git a/cmd/burrow/commands/start.go b/cmd/burrow/commands/start.go
index 7d112ffb2f27e790826ae0ce0309a7166bb06116..67b43bb0e78f9911e93791313435810edcd85b1f 100644
--- a/cmd/burrow/commands/start.go
+++ b/cmd/burrow/commands/start.go
@@ -3,9 +3,9 @@ package commands
 import (
 	"context"
 
-	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/config"
 	"github.com/hyperledger/burrow/config/source"
+	"github.com/hyperledger/burrow/crypto"
 	logging_config "github.com/hyperledger/burrow/logging/config"
 	"github.com/jawher/mow.cli"
 )
@@ -71,7 +71,7 @@ func Start(output Output) func(cmd *cli.Cmd) {
 
 			// Which validator am I?
 			if *validatorAddressOpt != "" {
-				address, err := acm.AddressFromHexString(*validatorAddressOpt)
+				address, err := crypto.AddressFromHexString(*validatorAddressOpt)
 				if err != nil {
 					output.Fatalf("could not read address for validator in '%s'", *validatorAddressOpt)
 				}
diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go
index cddf19edc8d799e63f726b197ee34357adb0a7df..28930dee9825417e16a5ef3d5a7af338fe7f4bd4 100644
--- a/cmd/burrow/main.go
+++ b/cmd/burrow/main.go
@@ -36,6 +36,9 @@ func burrow(output commands.Output) *cli.Cli {
 		"Create Burrow configuration by consuming a GenesisDoc or GenesisSpec, creating keys, and emitting the config",
 		commands.Configure(output))
 
+	app.Command("keys", "A tool for doing a bunch of cool stuff with keys",
+		commands.Keys(output))
+
 	return app
 }
 
diff --git a/config/config.go b/config/config.go
index 3ce6d2f83ce83178970ed7e7bd8d7b3a0b845a11..1a73e9faa4b9c8d075e1f5365b46230b0bd694d9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -5,11 +5,11 @@ import (
 
 	"context"
 
-	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/config/source"
 	"github.com/hyperledger/burrow/consensus/tendermint"
 	"github.com/hyperledger/burrow/consensus/tendermint/validator"
 	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
@@ -24,8 +24,8 @@ const DefaultGenesisDocJSONFileName = "genesis.json"
 
 type BurrowConfig struct {
 	// Set on startup
-	ValidatorAddress    *acm.Address `json:",omitempty" toml:",omitempty"`
-	ValidatorPassphrase *string      `json:",omitempty" toml:",omitempty"`
+	ValidatorAddress    *crypto.Address `json:",omitempty" toml:",omitempty"`
+	ValidatorPassphrase *string         `json:",omitempty" toml:",omitempty"`
 	// From config file
 	GenesisDoc *genesis.GenesisDoc                `json:",omitempty" toml:",omitempty"`
 	Tendermint *tendermint.BurrowTendermintConfig `json:",omitempty" toml:",omitempty"`
@@ -55,7 +55,18 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) {
 	if err != nil {
 		return nil, fmt.Errorf("could not generate logger from logging config: %v", err)
 	}
-	keyClient := keys.NewKeyClient(conf.Keys.URL, logger)
+	var keyClient keys.KeyClient
+	var keyStore keys.KeyStore
+	if conf.Keys.RemoteAddress != "" {
+		keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logger)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		keyStore = keys.NewKeyStore(conf.Keys.KeysDirectory)
+		keyClient = keys.NewLocalKeyClient(keyStore, logger)
+	}
+
 	val, err := keys.Addressable(keyClient, *conf.ValidatorAddress)
 	if err != nil {
 		return nil, fmt.Errorf("could not get validator addressable from keys client: %v", err)
@@ -70,8 +81,8 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) {
 		}
 	}
 
-	return core.NewKernel(ctx, keyClient, privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC,
-		exeOptions, logger)
+	return core.NewKernel(ctx, keyClient, privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC, conf.Keys,
+		&keyStore, exeOptions, logger)
 }
 
 func (conf *BurrowConfig) JSONString() string {
diff --git a/consensus/tendermint/query/node_view.go b/consensus/tendermint/query/node_view.go
index 566a93e377e983cc750b8b1cc3270bedf968332a..8f9539956e40233f2cf6e1fe4733e37ab1a18afb 100644
--- a/consensus/tendermint/query/node_view.go
+++ b/consensus/tendermint/query/node_view.go
@@ -3,8 +3,10 @@ package query
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/consensus/tendermint"
+	"github.com/hyperledger/burrow/crypto"
+	tm_crypto "github.com/tendermint/go-crypto"
+
 	"github.com/hyperledger/burrow/txs"
 	"github.com/tendermint/tendermint/consensus"
 	ctypes "github.com/tendermint/tendermint/consensus/types"
@@ -24,8 +26,10 @@ func NewNodeView(tmNode *tendermint.Node, txDecoder txs.Decoder) *NodeView {
 	}
 }
 
-func (nv *NodeView) PrivValidatorPublicKey() (acm.PublicKey, error) {
-	return acm.PublicKeyFromGoCryptoPubKey(nv.tmNode.PrivValidator().GetPubKey())
+func (nv *NodeView) PrivValidatorPublicKey() (crypto.PublicKey, error) {
+	pub := nv.tmNode.PrivValidator().GetPubKey().Unwrap().(tm_crypto.PubKeyEd25519)
+
+	return crypto.PublicKeyFromBytes(pub[:], crypto.CurveTypeEd25519)
 }
 
 func (nv *NodeView) NodeInfo() p2p.NodeInfo {
diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go
index 261bba24ffd74f66ea78344991caad09a5ebe68f..a83dbfa97b7b5752112a96263ba584e4b43ecbc6 100644
--- a/consensus/tendermint/tendermint.go
+++ b/consensus/tendermint/tendermint.go
@@ -17,6 +17,7 @@ import (
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/txs"
 	abci_types "github.com/tendermint/abci/types"
+	tm_crypto "github.com/tendermint/go-crypto"
 	"github.com/tendermint/tendermint/config"
 	"github.com/tendermint/tendermint/node"
 	"github.com/tendermint/tendermint/proxy"
@@ -101,8 +102,10 @@ func BroadcastTxAsyncFunc(validator *Node, txEncoder txs.Encoder) func(tx txs.Tx
 func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tm_types.GenesisDoc {
 	validators := make([]tm_types.GenesisValidator, len(burrowGenesisDoc.Validators))
 	for i, validator := range burrowGenesisDoc.Validators {
+		tm := tm_crypto.PubKeyEd25519{}
+		copy(tm[:], validator.PublicKey.RawBytes())
 		validators[i] = tm_types.GenesisValidator{
-			PubKey: validator.PublicKey.PubKey,
+			PubKey: tm_crypto.PubKey{tm},
 			Name:   validator.Name,
 			Power:  int64(validator.Amount),
 		}
diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go
index 50c6fdd99180c46beeedbb5bcc608895a7aaa926..4126d3d6e4e798dfdaf5dd8e897d47d937090959 100644
--- a/consensus/tendermint/validator/priv_validator_memory.go
+++ b/consensus/tendermint/validator/priv_validator_memory.go
@@ -2,7 +2,8 @@ package validator
 
 import (
 	acm "github.com/hyperledger/burrow/account"
-	"github.com/tendermint/go-crypto"
+	"github.com/hyperledger/burrow/crypto"
+	tm_crypto "github.com/tendermint/go-crypto"
 	tm_types "github.com/tendermint/tendermint/types"
 	val_types "github.com/tendermint/tendermint/types/priv_validator"
 )
@@ -17,7 +18,7 @@ var _ tm_types.PrivValidator = &privValidatorMemory{}
 
 // Create a PrivValidator with in-memory state that takes an addressable representing the validator identity
 // and a signer providing private signing for that identity.
-func NewPrivValidatorMemory(addressable acm.Addressable, signer acm.Signer) *privValidatorMemory {
+func NewPrivValidatorMemory(addressable acm.Addressable, signer crypto.Signer) *privValidatorMemory {
 	return &privValidatorMemory{
 		Addressable:    addressable,
 		Signer:         asTendermintSigner(signer),
@@ -29,8 +30,10 @@ func (pvm *privValidatorMemory) GetAddress() tm_types.Address {
 	return pvm.Address().Bytes()
 }
 
-func (pvm *privValidatorMemory) GetPubKey() crypto.PubKey {
-	return pvm.PublicKey().PubKey
+func (pvm *privValidatorMemory) GetPubKey() tm_crypto.PubKey {
+	tm := tm_crypto.PubKeyEd25519{}
+	copy(tm[:], pvm.PublicKey().RawBytes())
+	return tm_crypto.PubKey{tm}
 }
 
 // TODO: consider persistence to disk/database to avoid double signing after a crash
@@ -48,18 +51,20 @@ func (pvm *privValidatorMemory) SignHeartbeat(chainID string, heartbeat *tm_type
 	return err
 }
 
-func asTendermintSigner(signer acm.Signer) tm_types.Signer {
+func asTendermintSigner(signer crypto.Signer) tm_types.Signer {
 	return tendermintSigner{Signer: signer}
 }
 
 type tendermintSigner struct {
-	acm.Signer
+	crypto.Signer
 }
 
-func (tms tendermintSigner) Sign(msg []byte) (crypto.Signature, error) {
+func (tms tendermintSigner) Sign(msg []byte) (tm_crypto.Signature, error) {
 	sig, err := tms.Signer.Sign(msg)
 	if err != nil {
-		return crypto.Signature{}, err
+		return tm_crypto.Signature{}, err
 	}
-	return sig.GoCryptoSignature(), nil
+	tm_sig := tm_crypto.SignatureEd25519{}
+	copy(tm_sig[:], sig.RawBytes())
+	return tm_crypto.Signature{tm_sig}, nil
 }
diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go
index b97c7986d1463c20657b3116ded733f8eb599651..8a0e5a46d47526e632c5903518cab7349b1fc75f 100644
--- a/core/integration/test_wrapper.go
+++ b/core/integration/test_wrapper.go
@@ -28,6 +28,7 @@ import (
 	"github.com/hyperledger/burrow/consensus/tendermint/validator"
 	"github.com/hyperledger/burrow/core"
 	"github.com/hyperledger/burrow/genesis"
+	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/keys/mock"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/config"
@@ -80,8 +81,8 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes
 	validatorAccount := privateAccounts[0]
 	privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount)
 	keyClient := mock.NewKeyClient(privateAccounts...)
-	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(),
-		nil, logger)
+	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(),
+		nil, nil, logger)
 	if err != nil {
 		panic(err)
 	}
diff --git a/core/kernel.go b/core/kernel.go
index 4f3df68b9d2e60cb391e81492c4d7d1c9ef3b1a8..437c43fcb9f24a07307ac7f186fa1271d6188912 100644
--- a/core/kernel.go
+++ b/core/kernel.go
@@ -17,6 +17,7 @@ package core
 import (
 	"context"
 	"fmt"
+	"net"
 	"net/http"
 	_ "net/http/pprof"
 	"os"
@@ -33,6 +34,7 @@ import (
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/process"
@@ -44,6 +46,7 @@ import (
 	tm_config "github.com/tendermint/tendermint/config"
 	tm_types "github.com/tendermint/tendermint/types"
 	dbm "github.com/tendermint/tmlibs/db"
+	"google.golang.org/grpc"
 )
 
 const (
@@ -65,8 +68,8 @@ type Kernel struct {
 }
 
 func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_types.PrivValidator,
-	genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig,
-	exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) {
+	genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig,
+	keyStore *keys.KeyStore, exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) {
 
 	logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC)
 	tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1))
@@ -111,7 +114,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 	launchers := []process.Launcher{
 		{
 			Name:     "Profiling Server",
-			Disabled: rpcConfig.Profiler.Disabled,
+			Disabled: !rpcConfig.Profiler.Enabled,
 			Launch: func() (process.Process, error) {
 				debugServer := &http.Server{
 					Addr: ":6060",
@@ -170,7 +173,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 		},
 		{
 			Name:     "RPC/tm",
-			Disabled: rpcConfig.TM.Disabled,
+			Disabled: !rpcConfig.TM.Enabled,
 			Launch: func() (process.Process, error) {
 				listener, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, emitter, logger)
 				if err != nil {
@@ -181,7 +184,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 		},
 		{
 			Name:     "RPC/V0",
-			Disabled: rpcConfig.V0.Disabled,
+			Disabled: !rpcConfig.V0.Enabled,
 			Launch: func() (process.Process, error) {
 				codec := v0.NewTCodec()
 				jsonServer := v0.NewJSONServer(v0.NewJSONService(codec, service, logger))
@@ -199,6 +202,37 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 				return serveProcess, nil
 			},
 		},
+		{
+			Name:     "grpc service",
+			Disabled: !rpcConfig.GRPC.Enabled,
+			Launch: func() (process.Process, error) {
+				listen, err := net.Listen("tcp", rpcConfig.GRPC.ListenAddress)
+				if err != nil {
+					return nil, err
+				}
+
+				grpcServer := grpc.NewServer()
+				var ks keys.KeyStore
+				if keyStore != nil {
+					ks = *keyStore
+				}
+
+				if keyConfig.GRPCServiceEnabled {
+					if keyStore == nil {
+						ks = keys.NewKeyStore(keyConfig.KeysDirectory)
+					}
+					pbkeys.RegisterKeysServer(grpcServer, &ks)
+				}
+
+				go grpcServer.Serve(listen)
+
+				return process.ShutdownFunc(func(ctx context.Context) error {
+					grpcServer.Stop()
+					// listener is closed for us
+					return nil
+				}), nil
+			},
+		},
 	}
 
 	return &Kernel{
diff --git a/core/kernel_test.go b/core/kernel_test.go
index 5cd06d36e46d9946ea03a9f4a1832263f1ca1d24..e02ef7cd60463e64b0590a102be606cd7693c0e3 100644
--- a/core/kernel_test.go
+++ b/core/kernel_test.go
@@ -12,7 +12,7 @@ import (
 	"github.com/hyperledger/burrow/consensus/tendermint"
 	"github.com/hyperledger/burrow/consensus/tendermint/validator"
 	"github.com/hyperledger/burrow/genesis"
-	"github.com/hyperledger/burrow/keys/mock"
+	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/stretchr/testify/assert"
@@ -65,8 +65,10 @@ func bootWaitBlocksShutdown(privValidator tm_types.PrivValidator, genesisDoc *ge
 	tmConf *tm_config.Config, logger *logging.Logger,
 	blockChecker func(block *tm_types.EventDataNewBlock) (cont bool)) error {
 
-	kern, err := NewKernel(context.Background(), mock.NewKeyClient(), privValidator, genesisDoc, tmConf,
-		rpc.DefaultRPCConfig(), nil, logger)
+	keyStore := keys.NewKeyStore(keys.DefaultKeysDir)
+	keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger())
+	kern, err := NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf,
+		rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), &keyStore, nil, logger)
 	if err != nil {
 		return err
 	}
diff --git a/account/address.go b/crypto/address.go
similarity index 99%
rename from account/address.go
rename to crypto/address.go
index 70353baccef9a398392e0a7be6d596e611523064..a72f8c02d9d4456d4e638780d902c0e3ecc09123 100644
--- a/account/address.go
+++ b/crypto/address.go
@@ -1,4 +1,4 @@
-package account
+package crypto
 
 import (
 	"bytes"
diff --git a/account/address_test.go b/crypto/address_test.go
similarity index 99%
rename from account/address_test.go
rename to crypto/address_test.go
index 5a1572b34d1d763435b2d3961d597ab9a56dd1e5..cf21319eaa9037307b62473c5258223ab539cca0 100644
--- a/account/address_test.go
+++ b/crypto/address_test.go
@@ -1,4 +1,4 @@
-package account
+package crypto
 
 import (
 	"encoding/json"
diff --git a/crypto/crypto.go b/crypto/crypto.go
new file mode 100644
index 0000000000000000000000000000000000000000..da0e85dd0af80b0c12d026c551fd0b6ae8ed0389
--- /dev/null
+++ b/crypto/crypto.go
@@ -0,0 +1,361 @@
+package crypto
+
+import (
+	"bytes"
+	crand "crypto/rand"
+	"crypto/sha256"
+	"encoding/json"
+	"fmt"
+	"io"
+
+	"github.com/btcsuite/btcd/btcec"
+	tm_crypto "github.com/tendermint/go-crypto"
+	"github.com/tmthrgd/go-hex"
+	"golang.org/x/crypto/ed25519"
+	"golang.org/x/crypto/ripemd160"
+)
+
+type CurveType int8
+
+const (
+	CurveTypeSecp256k1 CurveType = iota
+	CurveTypeEd25519
+)
+
+func (k CurveType) String() string {
+	switch k {
+	case CurveTypeSecp256k1:
+		return "secp256k1"
+	case CurveTypeEd25519:
+		return "ed25519"
+	default:
+		return "unknown"
+	}
+}
+
+func CurveTypeFromString(s string) (CurveType, error) {
+	switch s {
+	case "secp256k1":
+		return CurveTypeSecp256k1, nil
+	case "ed25519":
+		return CurveTypeEd25519, nil
+	default:
+		var k CurveType
+		return k, ErrInvalidCurve(s)
+	}
+}
+
+func (p PublicKey) AddressHashType() string {
+	switch p.CurveType {
+	case CurveTypeEd25519:
+		return "go-crypto-0.5.0"
+	case CurveTypeSecp256k1:
+		return "btc"
+	default:
+		return ""
+	}
+}
+
+type ErrInvalidCurve string
+
+func (err ErrInvalidCurve) Error() string {
+	return fmt.Sprintf("invalid curve type")
+}
+
+// The types in this file allow us to control serialisation of keys and signatures, as well as the interface
+// exposed regardless of crypto library
+
+type Signer interface {
+	Sign(msg []byte) (Signature, error)
+}
+
+// PublicKey
+type PublicKey struct {
+	CurveType CurveType
+	PublicKey []byte
+}
+
+type PrivateKey struct {
+	CurveType  CurveType
+	PublicKey  []byte
+	PrivateKey []byte
+}
+
+type PublicKeyJSON struct {
+	CurveType string
+	PublicKey string
+}
+
+func (p PublicKey) MarshalJSON() ([]byte, error) {
+	jStruct := PublicKeyJSON{
+		CurveType: p.CurveType.String(),
+		PublicKey: hex.EncodeUpperToString(p.PublicKey),
+	}
+	txt, err := json.Marshal(jStruct)
+	return txt, err
+}
+
+func (p PublicKey) MarshalText() ([]byte, error) {
+	return p.MarshalJSON()
+}
+
+func (p *PublicKey) UnmarshalJSON(text []byte) error {
+	var jStruct PublicKeyJSON
+	err := json.Unmarshal(text, &jStruct)
+	if err != nil {
+		return err
+	}
+	CurveType, err := CurveTypeFromString(jStruct.CurveType)
+	if err != nil {
+		return err
+	}
+	bs, err := hex.DecodeString(jStruct.PublicKey)
+	if err != nil {
+		return err
+	}
+	p.CurveType = CurveType
+	p.PublicKey = bs
+	return nil
+}
+
+func (p *PublicKey) UnmarshalText(text []byte) error {
+	return p.UnmarshalJSON(text)
+}
+
+func (p PublicKey) IsValid() bool {
+	switch p.CurveType {
+	case CurveTypeEd25519:
+		return len(p.PublicKey) == ed25519.PublicKeySize
+	case CurveTypeSecp256k1:
+		return len(p.PublicKey) == btcec.PubKeyBytesLenCompressed
+	default:
+		return false
+	}
+}
+func (p PublicKey) Verify(msg []byte, signature Signature) bool {
+	switch p.CurveType {
+	case CurveTypeEd25519:
+		return ed25519.Verify(p.PublicKey, msg, signature.Signature[:])
+	case CurveTypeSecp256k1:
+		pub, err := btcec.ParsePubKey(p.PublicKey, btcec.S256())
+		if err != nil {
+			return false
+		}
+		sig, err := btcec.ParseDERSignature(signature.Signature, btcec.S256())
+		if err != nil {
+			return false
+		}
+		return sig.Verify(msg, pub)
+	default:
+		panic(fmt.Sprintf("invalid curve type"))
+	}
+}
+
+func (p PublicKey) Address() Address {
+	switch p.CurveType {
+	case CurveTypeEd25519:
+		// FIMXE: tendermint go-crypto-0.5.0 uses weird scheme, this is fixed in 0.6.0
+		tmPubKey := new(tm_crypto.PubKeyEd25519)
+		copy(tmPubKey[:], p.PublicKey)
+		addr, _ := AddressFromBytes(tmPubKey.Address())
+		return addr
+	case CurveTypeSecp256k1:
+		sha := sha256.New()
+		sha.Write(p.PublicKey[:])
+
+		hash := ripemd160.New()
+		hash.Write(sha.Sum(nil))
+		addr, _ := AddressFromBytes(hash.Sum(nil))
+		return addr
+	default:
+		panic(fmt.Sprintf("unknown CurveType %d", p.CurveType))
+	}
+}
+
+func (p PublicKey) RawBytes() []byte {
+	return p.PublicKey[:]
+}
+
+func (p PublicKey) String() string {
+	return hex.EncodeUpperToString(p.PublicKey)
+}
+
+// Signable is an interface for all signable things.
+// It typically removes signatures before serializing.
+type Signable interface {
+	WriteSignBytes(chainID string, w io.Writer, n *int, err *error)
+}
+
+// SignBytes is a convenience method for getting the bytes to sign of a Signable.
+func SignBytes(chainID string, o Signable) []byte {
+	buf, n, err := new(bytes.Buffer), new(int), new(error)
+	o.WriteSignBytes(chainID, buf, n, err)
+	if *err != nil {
+		panic(fmt.Sprintf("could not write sign bytes for a signable: %s", *err))
+	}
+	return buf.Bytes()
+}
+
+// Currently this is a stub that reads the raw bytes returned by key_client and returns
+// an ed25519 public key.
+func PublicKeyFromBytes(bs []byte, curveType CurveType) (PublicKey, error) {
+	switch curveType {
+	case CurveTypeEd25519:
+		if len(bs) != ed25519.PublicKeySize {
+			return PublicKey{}, fmt.Errorf("bytes passed have length %v but ed25519 public keys have %v bytes",
+				len(bs), ed25519.PublicKeySize)
+		}
+	case CurveTypeSecp256k1:
+		if len(bs) != btcec.PubKeyBytesLenCompressed {
+			return PublicKey{}, fmt.Errorf("bytes passed have length %v but secp256k1 public keys have %v bytes",
+				len(bs), btcec.PubKeyBytesLenCompressed)
+		}
+	default:
+		return PublicKey{}, ErrInvalidCurve(curveType)
+	}
+
+	return PublicKey{PublicKey: bs, CurveType: curveType}, nil
+}
+
+func (p PrivateKey) RawBytes() []byte {
+	return p.PrivateKey
+}
+
+func (p PrivateKey) Sign(msg []byte) (Signature, error) {
+	switch p.CurveType {
+	case CurveTypeEd25519:
+		if len(p.PrivateKey) != ed25519.PrivateKeySize {
+			return Signature{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes",
+				len(p.PrivateKey), ed25519.PrivateKeySize)
+		}
+		privKey := ed25519.PrivateKey(p.PrivateKey)
+		return Signature{ed25519.Sign(privKey, msg)}, nil
+	case CurveTypeSecp256k1:
+		if len(p.PrivateKey) != btcec.PrivKeyBytesLen {
+			return Signature{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes",
+				len(p.PrivateKey), btcec.PrivKeyBytesLen)
+		}
+		privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), p.PrivateKey)
+
+		sig, err := privKey.Sign(msg)
+		if err != nil {
+			return Signature{}, err
+		}
+		return Signature{Signature: sig.Serialize()}, nil
+	default:
+		return Signature{}, ErrInvalidCurve(p.CurveType)
+	}
+}
+
+func (p PrivateKey) GetPublicKey() PublicKey {
+	return PublicKey{CurveType: p.CurveType, PublicKey: p.PublicKey}
+}
+
+func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKey, error) {
+	switch curveType {
+	case CurveTypeEd25519:
+		if len(privKeyBytes) != ed25519.PrivateKeySize {
+			return PrivateKey{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes",
+				len(privKeyBytes), ed25519.PrivateKeySize)
+		}
+		return PrivateKey{PrivateKey: privKeyBytes, PublicKey: privKeyBytes[32:], CurveType: CurveTypeEd25519}, nil
+	case CurveTypeSecp256k1:
+		if len(privKeyBytes) != btcec.PrivKeyBytesLen {
+			return PrivateKey{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes",
+				len(privKeyBytes), btcec.PrivKeyBytesLen)
+		}
+		privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
+		return PrivateKey{PrivateKey: privKey.Serialize(), PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil
+	default:
+		return PrivateKey{}, ErrInvalidCurve(curveType)
+	}
+}
+
+func GeneratePrivateKey(random io.Reader, curveType CurveType) (PrivateKey, error) {
+	if random == nil {
+		random = crand.Reader
+	}
+	switch curveType {
+	case CurveTypeEd25519:
+		_, priv, err := ed25519.GenerateKey(random)
+		if err != nil {
+			return PrivateKey{}, err
+		}
+		return PrivateKeyFromRawBytes(priv, CurveTypeEd25519)
+	case CurveTypeSecp256k1:
+		privKeyBytes := make([]byte, 32)
+		_, err := random.Read(privKeyBytes)
+		if err != nil {
+			return PrivateKey{}, err
+		}
+		return PrivateKeyFromRawBytes(privKeyBytes, CurveTypeSecp256k1)
+	default:
+		return PrivateKey{}, ErrInvalidCurve(curveType)
+	}
+}
+
+func PrivateKeyFromSecret(secret string, curveType CurveType) PrivateKey {
+	hasher := sha256.New()
+	hasher.Write(([]byte)(secret))
+	// No error from a buffer
+	privateKey, _ := GeneratePrivateKey(bytes.NewBuffer(hasher.Sum(nil)), curveType)
+	return privateKey
+}
+
+// Ensures the last 32 bytes of the ed25519 private key is the public key derived from the first 32 private bytes
+func EnsureEd25519PrivateKeyCorrect(candidatePrivateKey ed25519.PrivateKey) error {
+	if len(candidatePrivateKey) != ed25519.PrivateKeySize {
+		return fmt.Errorf("ed25519 key has size %v but %v bytes passed as key", ed25519.PrivateKeySize,
+			len(candidatePrivateKey))
+	}
+	_, derivedPrivateKey, err := ed25519.GenerateKey(bytes.NewBuffer(candidatePrivateKey))
+	if err != nil {
+		return err
+	}
+	if !bytes.Equal(derivedPrivateKey, candidatePrivateKey) {
+		return fmt.Errorf("ed25519 key generated from prefix of %X should equal %X, but is %X",
+			candidatePrivateKey, candidatePrivateKey, derivedPrivateKey)
+	}
+	return nil
+}
+
+func ChainSign(signer Signer, chainID string, o Signable) (Signature, error) {
+	sig, err := signer.Sign(SignBytes(chainID, o))
+	if err != nil {
+		return Signature{}, err
+	}
+	return sig, nil
+}
+
+// Signature
+
+type Signature struct {
+	Signature []byte
+}
+
+// Currently this is a stub that reads the raw bytes returned by key_client and returns
+// an ed25519 signature.
+func SignatureFromBytes(bs []byte, curveType CurveType) (Signature, error) {
+	switch curveType {
+	case CurveTypeEd25519:
+		signatureEd25519 := Signature{}
+		if len(bs) != ed25519.SignatureSize {
+			return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes",
+				len(bs), ed25519.SignatureSize)
+		}
+		copy(signatureEd25519.Signature[:], bs)
+		return Signature{
+			Signature: bs,
+		}, nil
+	case CurveTypeSecp256k1:
+		return Signature{
+			Signature: bs,
+		}, nil
+	default:
+		return Signature{}, nil
+	}
+}
+
+func (sig Signature) RawBytes() []byte {
+	return sig.Signature
+}
diff --git a/account/crypto_test.go b/crypto/crypto_test.go
similarity index 95%
rename from account/crypto_test.go
rename to crypto/crypto_test.go
index d412e0fc4c83a2ffc4a08088f3ae8182ce90caf5..45e7c897d44a98894826950dcb51d81e29e9bfcd 100644
--- a/account/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -1,4 +1,4 @@
-package account
+package crypto
 
 import (
 	"bytes"
@@ -14,7 +14,7 @@ func TestGeneratePrivateKey(t *testing.T) {
 		1, 2, 3, 4, 5, 6, 7, 8,
 		1, 2, 3, 4, 5, 6, 7, 8,
 		1, 2, 3, 4, 5, 6, 7, 8,
-	}))
+	}), CurveTypeEd25519)
 	require.NoError(t, err)
 	assert.NoError(t, EnsureEd25519PrivateKeyCorrect(privateKey.RawBytes()))
 	badKey := privateKey.RawBytes()
diff --git a/crypto/helpers/helpers.go b/crypto/helpers/helpers.go
new file mode 100644
index 0000000000000000000000000000000000000000..deed990ebe07792e3a5d700bad521b46a881da1c
--- /dev/null
+++ b/crypto/helpers/helpers.go
@@ -0,0 +1,58 @@
+package helpers
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/tendermint/ed25519"
+	"github.com/tendermint/go-wire"
+	"golang.org/x/crypto/ripemd160"
+)
+
+type Signature interface {
+	IsZero() bool
+}
+
+const (
+	SignatureTypeEd25519 = byte(0x01)
+)
+
+type SignatureEd25519 [64]byte
+
+func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
+
+const (
+	PrivKeyTypeEd25519 = byte(0x01)
+)
+
+type PrivKeyEd25519 [64]byte
+
+const (
+	PubKeyTypeEd25519 = byte(0x01)
+)
+
+func (key PrivKeyEd25519) Sign(msg []byte) Signature {
+	privKeyBytes := [64]byte(key)
+	signatureBytes := ed25519.Sign(&privKeyBytes, msg)
+	return SignatureEd25519(*signatureBytes)
+}
+
+// Implements PubKey
+type PubKeyEd25519 [32]byte
+
+func (pubKey PubKeyEd25519) Address() []byte {
+	w, n, err := new(bytes.Buffer), new(int), new(error)
+	wire.WriteBinary(pubKey[:], w, n, err)
+	if *err != nil {
+		panic(fmt.Sprintf("failed to write tender public key: %v", err))
+	}
+	// append type byte
+	encodedPubkey := append([]byte{1}, w.Bytes()...)
+	hasher := ripemd160.New()
+	hasher.Write(encodedPubkey) // does not error
+	return hasher.Sum(nil)
+}
+
+type (
+	Hash [32]byte
+)
diff --git a/deployment/config.go b/deployment/config.go
index 8f1047b638d8465ae527fc887368add3842e61bd..b5ead42643ef360ee97f81b0b55f3c7b7ec96756 100644
--- a/deployment/config.go
+++ b/deployment/config.go
@@ -8,13 +8,13 @@ import (
 	"text/template"
 
 	"github.com/hyperledger/burrow/config"
-	"github.com/hyperledger/burrow/keys/mock"
+	"github.com/hyperledger/burrow/keys"
 	"github.com/pkg/errors"
 	"github.com/tmthrgd/go-hex"
 )
 
 type Package struct {
-	Keys         []*mock.Key
+	Keys         []*keys.Key
 	BurrowConfig *config.BurrowConfig
 }
 
diff --git a/deployment/config_test.go b/deployment/config_test.go
deleted file mode 100644
index 3a159238b538bcca6274ed2370e96f0c049229bf..0000000000000000000000000000000000000000
--- a/deployment/config_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package deployment
-
-import (
-	"encoding/json"
-	"fmt"
-	"testing"
-
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/keys/mock"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func TestMockKeyClient_DumpKeys(t *testing.T) {
-	keyClient := mock.NewKeyClient()
-	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	pkg := Package{Keys: keyClient.Keys()}
-	dump, err := pkg.Dump(DefaultDumpKeysFormat)
-	require.NoError(t, err)
-
-	// Check JSON equal
-	var keys struct{ Keys []*mock.Key }
-	err = json.Unmarshal([]byte(dump), &keys)
-	require.NoError(t, err)
-	bs, err := json.MarshalIndent(keys, "", "  ")
-	require.NoError(t, err)
-	assert.Equal(t, string(bs), dump)
-}
-
-func TestMockKeyClient_DumpKeysKubernetes(t *testing.T) {
-	keyClient := mock.NewKeyClient()
-	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	pkg := Package{Keys: keyClient.Keys()}
-	dump, err := pkg.Dump(KubernetesKeyDumpFormat)
-	require.NoError(t, err)
-	fmt.Println(dump)
-}
-
-func TestMockKeyClient_DumpKeysHelm(t *testing.T) {
-	keyClient := mock.NewKeyClient()
-	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	pkg := Package{Keys: keyClient.Keys()}
-	dump, err := pkg.Dump(HelmDumpKeysFormat)
-	require.NoError(t, err)
-	fmt.Println(dump)
-}
diff --git a/execution/accounts.go b/execution/accounts.go
index 7602367eb35c66dfe23535d38bf6718ab25863b3..ec9d663c002dd3aaf928a62a480d060a77c11a57 100644
--- a/execution/accounts.go
+++ b/execution/accounts.go
@@ -6,6 +6,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
 	burrow_sync "github.com/hyperledger/burrow/sync"
 )
@@ -20,7 +21,7 @@ type Accounts struct {
 
 type SigningAccount struct {
 	acm.Account
-	acm.Signer
+	crypto.Signer
 }
 
 type SequentialSigningAccount struct {
@@ -36,7 +37,7 @@ func NewAccounts(reader state.Reader, keyClient keys.KeyClient, mutexCount int)
 		keyClient: keyClient,
 	}
 }
-func (accs *Accounts) SigningAccount(address acm.Address, signer acm.Signer) (*SigningAccount, error) {
+func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signer) (*SigningAccount, error) {
 	account, err := state.GetMutableAccount(accs, address)
 	if err != nil {
 		return nil, err
@@ -58,7 +59,7 @@ func (accs *Accounts) SigningAccount(address acm.Address, signer acm.Signer) (*S
 	}, nil
 }
 
-func (accs *Accounts) SequentialSigningAccount(address acm.Address) *SequentialSigningAccount {
+func (accs *Accounts) SequentialSigningAccount(address crypto.Address) *SequentialSigningAccount {
 	signer := keys.Signer(accs.keyClient, address)
 	return &SequentialSigningAccount{
 		accountLocker: accs.Mutex(address.Bytes()),
diff --git a/execution/events/events.go b/execution/events/events.go
index 2d4dd548b17ff083dcfd4d9fb338e3c1af9935b9..b9aa92df754ccdb8acff76523a183aa63d9ad694 100644
--- a/execution/events/events.go
+++ b/execution/events/events.go
@@ -6,19 +6,19 @@ import (
 	"fmt"
 	"reflect"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/txs"
 	"github.com/tmthrgd/go-hex"
 )
 
-func EventStringAccountInput(addr acm.Address) string  { return fmt.Sprintf("Acc/%s/Input", addr) }
-func EventStringAccountOutput(addr acm.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) }
-func EventStringNameReg(name string) string            { return fmt.Sprintf("NameReg/%s", name) }
-func EventStringPermissions(name string) string        { return fmt.Sprintf("Permissions/%s", name) }
-func EventStringBond() string                          { return "Bond" }
-func EventStringUnbond() string                        { return "Unbond" }
-func EventStringRebond() string                        { return "Rebond" }
+func EventStringAccountInput(addr crypto.Address) string  { return fmt.Sprintf("Acc/%s/Input", addr) }
+func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) }
+func EventStringNameReg(name string) string               { return fmt.Sprintf("NameReg/%s", name) }
+func EventStringPermissions(name string) string           { return fmt.Sprintf("Permissions/%s", name) }
+func EventStringBond() string                             { return "Bond" }
+func EventStringUnbond() string                           { return "Unbond" }
+func EventStringRebond() string                           { return "Rebond" }
 
 // All txs fire EventDataTx, but only CallTx might have Return or Exception
 type EventDataTx struct {
@@ -65,7 +65,7 @@ func (edTx *EventDataTx) UnmarshalJSON(data []byte) error {
 
 // Publish/Subscribe
 func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscribable, subscriber string,
-	address acm.Address, txHash []byte, ch chan<- *txs.SendTx) error {
+	address crypto.Address, txHash []byte, ch chan<- *txs.SendTx) error {
 
 	query := sendTxQuery.And(event.QueryForEventID(EventStringAccountOutput(address))).
 		AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash))
@@ -80,7 +80,7 @@ func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscr
 	})
 }
 
-func PublishAccountOutput(publisher event.Publisher, address acm.Address, txHash []byte,
+func PublishAccountOutput(publisher event.Publisher, address crypto.Address, txHash []byte,
 	tx txs.Tx, ret []byte, exception string) error {
 
 	return event.PublishWithEventID(publisher, EventStringAccountOutput(address),
@@ -96,7 +96,7 @@ func PublishAccountOutput(publisher event.Publisher, address acm.Address, txHash
 		})
 }
 
-func PublishAccountInput(publisher event.Publisher, address acm.Address, txHash []byte,
+func PublishAccountInput(publisher event.Publisher, address crypto.Address, txHash []byte,
 	tx txs.Tx, ret []byte, exception string) error {
 
 	return event.PublishWithEventID(publisher, EventStringAccountInput(address),
diff --git a/execution/evm/accounts.go b/execution/evm/accounts.go
index 800e6269b1afb7f39c2fcf77a7e79722cc5d4147..1bd61df33a38a91f98fa338e4023c163c71e5053 100644
--- a/execution/evm/accounts.go
+++ b/execution/evm/accounts.go
@@ -2,6 +2,7 @@ package evm
 
 import (
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 )
@@ -19,7 +20,7 @@ func DeriveNewAccount(creator acm.MutableAccount, permissions ptypes.AccountPerm
 		"new_sequence", sequence+1)
 	creator.IncSequence()
 
-	addr := acm.NewContractAddress(creator.Address(), sequence)
+	addr := crypto.NewContractAddress(creator.Address(), sequence)
 
 	// Create account from address.
 	return acm.ConcreteAccount{
diff --git a/execution/evm/events/events.go b/execution/evm/events/events.go
index a9308bb5b075cfd6e6fe59a8de7d663ea86392e5..9ae628a7a829ac0c858811cd5643910abbffc7da 100644
--- a/execution/evm/events/events.go
+++ b/execution/evm/events/events.go
@@ -18,23 +18,23 @@ import (
 	"context"
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/tmthrgd/go-hex"
 )
 
 // Functions to generate eventId strings
 
-func EventStringAccountCall(addr acm.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) }
-func EventStringLogEvent(addr acm.Address) string    { return fmt.Sprintf("Log/%s", addr) }
+func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) }
+func EventStringLogEvent(addr crypto.Address) string    { return fmt.Sprintf("Log/%s", addr) }
 
 //----------------------------------------
 
 // EventDataCall fires when we call a contract, and when a contract calls another contract
 type EventDataCall struct {
 	CallData   *CallData
-	Origin     acm.Address
+	Origin     crypto.Address
 	TxHash     []byte
 	StackDepth int
 	Return     []byte
@@ -42,8 +42,8 @@ type EventDataCall struct {
 }
 
 type CallData struct {
-	Caller acm.Address
-	Callee acm.Address
+	Caller crypto.Address
+	Callee crypto.Address
 	Data   []byte
 	Value  uint64
 	Gas    uint64
@@ -51,7 +51,7 @@ type CallData struct {
 
 // EventDataLog fires when a contract executes the LOG opcode
 type EventDataLog struct {
-	Address acm.Address
+	Address crypto.Address
 	Topics  []Word256
 	Data    []byte
 	Height  uint64
@@ -62,7 +62,7 @@ type EventDataLog struct {
 // Subscribe to account call event - if TxHash is provided listens for a specifc Tx otherwise captures all, if
 // stackDepth is greater than or equal to 0 captures calls at a specific stack depth (useful for capturing the return
 // of the root call over recursive calls
-func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address acm.Address,
+func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address,
 	txHash []byte, stackDepth int, ch chan<- *EventDataCall) error {
 
 	query := event.QueryForEventID(EventStringAccountCall(address))
@@ -84,7 +84,7 @@ func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable,
 	})
 }
 
-func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address acm.Address,
+func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address,
 	ch chan<- *EventDataLog) error {
 
 	query := event.QueryForEventID(EventStringLogEvent(address))
@@ -98,7 +98,7 @@ func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, sub
 	})
 }
 
-func PublishAccountCall(publisher event.Publisher, address acm.Address, eventDataCall *EventDataCall) error {
+func PublishAccountCall(publisher event.Publisher, address crypto.Address, eventDataCall *EventDataCall) error {
 	return event.PublishWithEventID(publisher, EventStringAccountCall(address), eventDataCall,
 		map[string]interface{}{
 			"address":           address,
@@ -107,7 +107,7 @@ func PublishAccountCall(publisher event.Publisher, address acm.Address, eventDat
 		})
 }
 
-func PublishLogEvent(publisher event.Publisher, address acm.Address, eventDataLog *EventDataLog) error {
+func PublishLogEvent(publisher event.Publisher, address crypto.Address, eventDataLog *EventDataLog) error {
 	return event.PublishWithEventID(publisher, EventStringLogEvent(address), eventDataLog,
 		map[string]interface{}{"address": address})
 }
diff --git a/execution/evm/fake_app_state.go b/execution/evm/fake_app_state.go
index 7efbe82cd9e13d90ca7fa21b57d381f47f781f39..b618a48ad5b8a8885c032d6ec7ec6ea5c87c65f1 100644
--- a/execution/evm/fake_app_state.go
+++ b/execution/evm/fake_app_state.go
@@ -22,16 +22,17 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 )
 
 type FakeAppState struct {
-	accounts map[acm.Address]acm.Account
+	accounts map[crypto.Address]acm.Account
 	storage  map[string]Word256
 }
 
 var _ state.Writer = &FakeAppState{}
 
-func (fas *FakeAppState) GetAccount(addr acm.Address) (acm.Account, error) {
+func (fas *FakeAppState) GetAccount(addr crypto.Address) (acm.Account, error) {
 	account := fas.accounts[addr]
 	return account, nil
 }
@@ -41,7 +42,7 @@ func (fas *FakeAppState) UpdateAccount(account acm.Account) error {
 	return nil
 }
 
-func (fas *FakeAppState) RemoveAccount(address acm.Address) error {
+func (fas *FakeAppState) RemoveAccount(address crypto.Address) error {
 	_, ok := fas.accounts[address]
 	if !ok {
 		panic(fmt.Sprintf("Invalid account addr: %s", address))
@@ -52,7 +53,7 @@ func (fas *FakeAppState) RemoveAccount(address acm.Address) error {
 	return nil
 }
 
-func (fas *FakeAppState) GetStorage(addr acm.Address, key Word256) (Word256, error) {
+func (fas *FakeAppState) GetStorage(addr crypto.Address, key Word256) (Word256, error) {
 	_, ok := fas.accounts[addr]
 	if !ok {
 		panic(fmt.Sprintf("Invalid account addr: %s", addr))
@@ -66,7 +67,7 @@ func (fas *FakeAppState) GetStorage(addr acm.Address, key Word256) (Word256, err
 	}
 }
 
-func (fas *FakeAppState) SetStorage(addr acm.Address, key Word256, value Word256) error {
+func (fas *FakeAppState) SetStorage(addr crypto.Address, key Word256, value Word256) error {
 	_, ok := fas.accounts[addr]
 	if !ok {
 
diff --git a/execution/evm/log_event_test.go b/execution/evm/log_event_test.go
index 91808042a822a57643f624875f152c22412e9e84..500a97e7a9335a7c9bc7fc4137c7b8c9e41b7119 100644
--- a/execution/evm/log_event_test.go
+++ b/execution/evm/log_event_test.go
@@ -24,6 +24,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	"github.com/hyperledger/burrow/execution/evm/events"
@@ -46,15 +47,15 @@ func TestLog4(t *testing.T) {
 	cache := state.NewCache(st)
 	// Create accounts
 	account1 := acm.ConcreteAccount{
-		Address: acm.Address{1, 3, 5, 7, 9},
+		Address: crypto.Address{1, 3, 5, 7, 9},
 	}.MutableAccount()
 	account2 := acm.ConcreteAccount{
-		Address: acm.Address{2, 4, 6, 8, 10},
+		Address: crypto.Address{2, 4, 6, 8, 10},
 	}.MutableAccount()
 	st.accounts[account1.Address()] = account1
 	st.accounts[account2.Address()] = account2
 
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	emitter := event.NewEmitter(logging.NewNoopLogger())
 
diff --git a/execution/evm/snative.go b/execution/evm/snative.go
index 1bb3e89cf7ddd0fbafde63c0328cd29c9084c514..8afbd171c84ed8a05e72c948dcc231958bfd4ee8 100644
--- a/execution/evm/snative.go
+++ b/execution/evm/snative.go
@@ -22,6 +22,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/evm/abi"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
 	"github.com/hyperledger/burrow/logging"
@@ -227,7 +228,7 @@ func NewSNativeContract(comment, name string,
 }
 
 type ErrLacksSNativePermission struct {
-	Address acm.Address
+	Address crypto.Address
 	SNative string
 }
 
@@ -276,7 +277,7 @@ func (contract *SNativeContractDescription) Dispatch(state state.Writer, caller
 
 // We define the address of an SNative contact as the last 20 bytes of the sha3
 // hash of its name
-func (contract *SNativeContractDescription) Address() (address acm.Address) {
+func (contract *SNativeContractDescription) Address() (address crypto.Address) {
 	hash := sha3.Sha3([]byte(contract.Name))
 	copy(address[:], hash[len(hash)-abi.AddressLength:])
 	return
@@ -354,7 +355,7 @@ func hasBase(state state.Writer, caller acm.Account, args []byte, gas *uint64,
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, permNum := returnTwoArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetAccount(address)
 	if err != nil {
 		return nil, err
@@ -380,7 +381,7 @@ func setBase(stateWriter state.Writer, caller acm.Account, args []byte, gas *uin
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, permNum, permVal := returnThreeArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetMutableAccount(stateWriter, address)
 	if err != nil {
 		return nil, err
@@ -407,7 +408,7 @@ func unsetBase(stateWriter state.Writer, caller acm.Account, args []byte, gas *u
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, permNum := returnTwoArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetMutableAccount(stateWriter, address)
 	if err != nil {
 		return nil, err
@@ -460,7 +461,7 @@ func hasRole(state state.Writer, caller acm.Account, args []byte, gas *uint64,
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, role := returnTwoArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetAccount(address)
 	if err != nil {
 		return nil, err
@@ -481,7 +482,7 @@ func addRole(stateWriter state.Writer, caller acm.Account, args []byte, gas *uin
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, role := returnTwoArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetMutableAccount(stateWriter, address)
 	if err != nil {
 		return nil, err
@@ -503,7 +504,7 @@ func removeRole(stateWriter state.Writer, caller acm.Account, args []byte, gas *
 	logger *logging.Logger) (output []byte, err error) {
 
 	addrWord256, role := returnTwoArgs(args)
-	address := acm.AddressFromWord256(addrWord256)
+	address := crypto.AddressFromWord256(addrWord256)
 	acc, err := state.GetMutableAccount(stateWriter, address)
 	if err != nil {
 		return nil, err
diff --git a/execution/evm/snative_test.go b/execution/evm/snative_test.go
index 7c25aaf7910d884869ff6a43719a6f3120f9885c..3f5e5eae9cc0dba28c35f849dd587312b35f65b3 100644
--- a/execution/evm/snative_test.go
+++ b/execution/evm/snative_test.go
@@ -22,6 +22,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/evm/abi"
 	"github.com/hyperledger/burrow/execution/evm/asm/bc"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
@@ -66,10 +67,10 @@ func TestSNativeContractDescription_Dispatch(t *testing.T) {
 	contract := SNativeContracts()["Permissions"]
 	state := newAppState()
 	caller := acm.ConcreteAccount{
-		Address: acm.Address{1, 1, 1},
+		Address: crypto.Address{1, 1, 1},
 	}.MutableAccount()
 	grantee := acm.ConcreteAccount{
-		Address: acm.Address{2, 2, 2},
+		Address: crypto.Address{2, 2, 2},
 	}.MutableAccount()
 	state.UpdateAccount(grantee)
 
diff --git a/execution/evm/vm.go b/execution/evm/vm.go
index 32ea15dff619f8f8b1f9a8ea2d68d879fe9e3252..37e9ec0658cc31da92b6979453833772acb7d606 100644
--- a/execution/evm/vm.go
+++ b/execution/evm/vm.go
@@ -25,6 +25,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	"github.com/hyperledger/burrow/execution/evm/events"
@@ -68,8 +69,8 @@ func (err ErrPermission) Error() string {
 
 type ErrNestedCall struct {
 	NestedError error
-	Caller      acm.Address
-	Callee      acm.Address
+	Caller      crypto.Address
+	Callee      crypto.Address
 	StackDepth  int
 }
 
@@ -107,7 +108,7 @@ type Params struct {
 type VM struct {
 	memoryProvider   func() Memory
 	params           Params
-	origin           acm.Address
+	origin           crypto.Address
 	txHash           []byte
 	stackDepth       int
 	nestedCallErrors []ErrNestedCall
@@ -118,7 +119,7 @@ type VM struct {
 	dumpTokens       bool
 }
 
-func NewVM(params Params, origin acm.Address, txid []byte,
+func NewVM(params Params, origin crypto.Address, txid []byte,
 	logger *logging.Logger, options ...func(*VM)) *VM {
 	vm := &VM{
 		memoryProvider: DefaultDynamicMemoryProvider,
@@ -156,7 +157,7 @@ func HasPermission(stateWriter state.Writer, acc acm.Account, perm ptypes.PermFl
 	return value
 }
 
-func (vm *VM) fireCallEvent(exception *string, output *[]byte, callerAddress, calleeAddress acm.Address, input []byte, value uint64, gas *uint64) {
+func (vm *VM) fireCallEvent(exception *string, output *[]byte, callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64) {
 	// fire the post call event (including exception if applicable)
 	if vm.publisher != nil {
 		events.PublishAccountCall(vm.publisher, calleeAddress, &events.EventDataCall{
@@ -569,7 +570,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 			if useGasNegative(gas, GasGetAccount, &err) {
 				return nil, err
 			}
-			acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr))
+			acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr))
 			if errAcc != nil {
 				return nil, firstErr(err, errAcc)
 			}
@@ -665,7 +666,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 			if useGasNegative(gas, GasGetAccount, &err) {
 				return nil, err
 			}
-			acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr))
+			acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr))
 			if errAcc != nil {
 				return nil, firstErr(err, errAcc)
 			}
@@ -686,7 +687,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 			if useGasNegative(gas, GasGetAccount, &err) {
 				return nil, err
 			}
-			acc, errAcc := callState.GetAccount(acm.AddressFromWord256(addr))
+			acc, errAcc := callState.GetAccount(crypto.AddressFromWord256(addr))
 			if errAcc != nil {
 				return nil, firstErr(err, errAcc)
 			}
@@ -1015,13 +1016,13 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 					exception = callErr.Error()
 				}
 				// NOTE: these fire call go_events and not particular go_events for eg name reg or permissions
-				vm.fireCallEvent(&exception, &ret, callee.Address(), acm.AddressFromWord256(addr), args, value, &gasLimit)
+				vm.fireCallEvent(&exception, &ret, callee.Address(), crypto.AddressFromWord256(addr), args, value, &gasLimit)
 			} else {
 				// EVM contract
 				if useGasNegative(gas, GasGetAccount, &callErr) {
 					return nil, callErr
 				}
-				acc, errAcc := state.GetMutableAccount(callState, acm.AddressFromWord256(addr))
+				acc, errAcc := state.GetMutableAccount(callState, crypto.AddressFromWord256(addr))
 				if errAcc != nil {
 					return nil, firstErr(callErr, errAcc)
 				}
@@ -1045,7 +1046,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 						if !HasPermission(callState, caller, permission.CreateAccount) {
 							return nil, ErrPermission{"create_account"}
 						}
-						acc = acm.ConcreteAccount{Address: acm.AddressFromWord256(addr)}.MutableAccount()
+						acc = acm.ConcreteAccount{Address: crypto.AddressFromWord256(addr)}.MutableAccount()
 					}
 					// add account to the tx cache
 					callState.UpdateAccount(acc)
@@ -1128,7 +1129,7 @@ func (vm *VM) call(callState state.Cache, caller acm.Account, callee acm.Mutable
 			if useGasNegative(gas, GasGetAccount, &err) {
 				return nil, err
 			}
-			receiver, errAcc := state.GetMutableAccount(callState, acm.AddressFromWord256(addr))
+			receiver, errAcc := state.GetMutableAccount(callState, crypto.AddressFromWord256(addr))
 			if errAcc != nil {
 				return nil, firstErr(err, errAcc)
 			}
diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go
index edce8d7d8f0f057bab30d54e7d32adb88753dbfb..fcd008459d25238492445e8acf065ef7dce91b8a 100644
--- a/execution/evm/vm_test.go
+++ b/execution/evm/vm_test.go
@@ -26,6 +26,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	. "github.com/hyperledger/burrow/execution/evm/asm/bc"
@@ -45,7 +46,7 @@ var logger = logging.NewNoopLogger()
 
 func newAppState() *FakeAppState {
 	fas := &FakeAppState{
-		accounts: make(map[acm.Address]acm.Account),
+		accounts: make(map[crypto.Address]acm.Account),
 		storage:  make(map[string]Word256),
 	}
 	// For default permissions
@@ -68,14 +69,14 @@ func newAccount(seed ...byte) acm.MutableAccount {
 	hasher := ripemd160.New()
 	hasher.Write(seed)
 	return acm.ConcreteAccount{
-		Address: acm.MustAddressFromBytes(hasher.Sum(nil)),
+		Address: crypto.MustAddressFromBytes(hasher.Sum(nil)),
 	}.MutableAccount()
 }
 
 // Runs a basic loop
 func TestVM(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	// Create accounts
 	account1 := newAccount(1)
@@ -98,7 +99,7 @@ func TestVM(t *testing.T) {
 
 func TestSHL(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 	account1 := newAccount(1)
 	account2 := newAccount(1, 0, 1)
 
@@ -247,7 +248,7 @@ func TestSHL(t *testing.T) {
 
 func TestSHR(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 	account1 := newAccount(1)
 	account2 := newAccount(1, 0, 1)
 
@@ -400,7 +401,7 @@ func TestSHR(t *testing.T) {
 
 func TestSAR(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 	account1 := newAccount(1)
 	account2 := newAccount(1, 0, 1)
 
@@ -572,7 +573,7 @@ func TestSAR(t *testing.T) {
 //Test attempt to jump to bad destination (position 16)
 func TestJumpErr(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	// Create accounts
 	account1 := newAccount(1)
@@ -612,7 +613,7 @@ func TestSubcurrency(t *testing.T) {
 	//st.accounts[account1.Address()] = account1
 	//st.accounts[account2.Address()] = account2
 
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	var gas uint64 = 1000
 
@@ -642,7 +643,7 @@ func TestSubcurrency(t *testing.T) {
 //it is meant to test the implementation of the REVERT opcode
 func TestRevert(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	// Create accounts
 	account1 := newAccount(1)
@@ -675,7 +676,7 @@ func TestRevert(t *testing.T) {
 // Test sending tokens from a contract to another account
 func TestSendCall(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	// Create accounts
 	account1 := newAccount(1)
@@ -716,7 +717,7 @@ func TestSendCall(t *testing.T) {
 // and then run it with 1 gas unit less, expecting a failure
 func TestDelegateCallGas(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	inOff := 0
 	inSize := 0 // no call data
@@ -777,7 +778,7 @@ func TestMemoryBounds(t *testing.T) {
 	memoryProvider := func() Memory {
 		return NewDynamicMemory(1024, 2048)
 	}
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger, MemoryProvider(memoryProvider))
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger, MemoryProvider(memoryProvider))
 	caller, _ := makeAccountWithCode(cache, "caller", nil)
 	callee, _ := makeAccountWithCode(cache, "callee", nil)
 	gas := uint64(100000)
@@ -828,7 +829,7 @@ func TestMsgSender(t *testing.T) {
 	//st.accounts[account1.Address()] = account1
 	//st.accounts[account2.Address()] = account2
 
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	var gas uint64 = 100000
 
@@ -870,7 +871,7 @@ func TestMsgSender(t *testing.T) {
 
 func TestInvalid(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	// Create accounts
 	account1 := newAccount(1)
@@ -891,7 +892,7 @@ func TestInvalid(t *testing.T) {
 
 func TestReturnDataSize(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	accountName := "account2addresstests"
 
@@ -930,7 +931,7 @@ func TestReturnDataSize(t *testing.T) {
 
 func TestReturnDataCopy(t *testing.T) {
 	cache := state.NewCache(newAppState())
-	ourVm := NewVM(newParams(), acm.ZeroAddress, nil, logger)
+	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
 	accountName := "account2addresstests"
 
@@ -995,8 +996,8 @@ func returnWord() []byte {
 }
 
 func makeAccountWithCode(accountUpdater state.AccountUpdater, name string,
-	code []byte) (acm.MutableAccount, acm.Address) {
-	address, _ := acm.AddressFromBytes([]byte(name))
+	code []byte) (acm.MutableAccount, crypto.Address) {
+	address, _ := crypto.AddressFromBytes([]byte(name))
 	account := acm.ConcreteAccount{
 		Address:  address,
 		Balance:  9999999,
@@ -1011,7 +1012,7 @@ func makeAccountWithCode(accountUpdater state.AccountUpdater, name string,
 // and then waits for any exceptions transmitted by Data in the AccCall
 // event (in the case of no direct error from call we will block waiting for
 // at least 1 AccCall event)
-func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr acm.Address,
+func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address,
 	contractCode []byte, gas uint64) ([]byte, error) {
 	eventCh := make(chan *evm_events.EventDataCall)
 	output, err := runVM(eventCh, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas)
@@ -1030,7 +1031,7 @@ func runVMWaitError(vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAc
 // Subscribes to an AccCall, runs the vm, returns the output and any direct
 // exception
 func runVM(eventCh chan<- *evm_events.EventDataCall, vmCache state.Cache, ourVm *VM, caller, callee acm.MutableAccount,
-	subscribeAddr acm.Address, contractCode []byte, gas uint64) ([]byte, error) {
+	subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) {
 
 	// we need to catch the event from the CALL to check for exceptions
 	emitter := event.NewEmitter(logging.NewNoopLogger())
@@ -1052,7 +1053,7 @@ func runVM(eventCh chan<- *evm_events.EventDataCall, vmCache state.Cache, ourVm
 }
 
 // this is code to call another contract (hardcoded as addr)
-func callContractCode(addr acm.Address) []byte {
+func callContractCode(addr crypto.Address) []byte {
 	gas1, gas2 := byte(0x1), byte(0x1)
 	value := byte(0x69)
 	inOff, inSize := byte(0x0), byte(0x0) // no call data
@@ -1109,7 +1110,7 @@ func TestBytecode(t *testing.T) {
 		[]byte{},
 		MustSplice(MustSplice(MustSplice())))
 
-	contractAccount := &acm.ConcreteAccount{Address: acm.AddressFromWord256(Int64ToWord256(102))}
+	contractAccount := &acm.ConcreteAccount{Address: crypto.AddressFromWord256(Int64ToWord256(102))}
 	addr := contractAccount.Address
 	gas1, gas2 := byte(0x1), byte(0x1)
 	value := byte(0x69)
diff --git a/execution/execution.go b/execution/execution.go
index a26646e00096aba66eaf2cb4bb1ee33190c36091..3e7068f2408195bd4036747ec6d147c807c0a43b 100644
--- a/execution/execution.go
+++ b/execution/execution.go
@@ -23,6 +23,7 @@ import (
 	"github.com/hyperledger/burrow/account/state"
 	"github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/evm"
@@ -111,14 +112,14 @@ func newExecutor(name string, runCall bool, backend *State, chainID string, tip
 // to always access the freshest mempool state as needed by accounts.SequentialSigningAccount
 //
 // Accounts
-func (exe *executor) GetAccount(address acm.Address) (acm.Account, error) {
+func (exe *executor) GetAccount(address crypto.Address) (acm.Account, error) {
 	exe.RLock()
 	defer exe.RUnlock()
 	return exe.stateCache.GetAccount(address)
 }
 
 // Storage
-func (exe *executor) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) {
+func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	exe.RLock()
 	defer exe.RUnlock()
 	return exe.stateCache.GetStorage(address, key)
@@ -196,7 +197,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) {
 			return err
 		}
 
-		signBytes := acm.SignBytes(exe.chainID, tx)
+		signBytes := crypto.SignBytes(exe.chainID, tx)
 		inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
 		if err != nil {
 			return err
@@ -270,7 +271,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) {
 				"tx_input", tx.Input)
 			return err
 		}
-		signBytes := acm.SignBytes(exe.chainID, tx)
+		signBytes := crypto.SignBytes(exe.chainID, tx)
 		err = validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
 			logger.InfoMsg("validateInput failed",
@@ -472,7 +473,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) {
 				"tx_input", tx.Input)
 			return err
 		}
-		signBytes := acm.SignBytes(exe.chainID, tx)
+		signBytes := crypto.SignBytes(exe.chainID, tx)
 		err = validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
 			logger.InfoMsg("validateInput failed",
@@ -783,7 +784,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) {
 				"tx_input", tx.Input)
 			return err
 		}
-		signBytes := acm.SignBytes(exe.chainID, tx)
+		signBytes := crypto.SignBytes(exe.chainID, tx)
 		err = validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
 			logger.InfoMsg("validateInput failed",
@@ -876,7 +877,7 @@ func (exe *executor) Execute(tx txs.Tx) (err error) {
 	}
 }
 
-func mutatePermissions(stateReader state.Reader, address acm.Address,
+func mutatePermissions(stateReader state.Reader, address crypto.Address,
 	mutator func(*ptypes.AccountPermissions) error) (acm.Account, error) {
 
 	account, err := stateReader.GetAccount(address)
@@ -1025,9 +1026,9 @@ func execBlock(s *State, block *txs.Block, blockPartsHeader txs.PartSetHeader) e
 // or it must be specified in the TxInput.  If redeclared,
 // the TxInput is modified and input.PublicKey() set to nil.
 func getInputs(accountGetter state.AccountGetter,
-	ins []*txs.TxInput) (map[acm.Address]acm.MutableAccount, error) {
+	ins []*txs.TxInput) (map[crypto.Address]acm.MutableAccount, error) {
 
-	accounts := map[acm.Address]acm.MutableAccount{}
+	accounts := map[crypto.Address]acm.MutableAccount{}
 	for _, in := range ins {
 		// Account shouldn't be duplicated
 		if _, ok := accounts[in.Address]; ok {
@@ -1049,10 +1050,10 @@ func getInputs(accountGetter state.AccountGetter,
 	return accounts, nil
 }
 
-func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount,
-	outs []*txs.TxOutput, logger *logging.Logger) (map[acm.Address]acm.MutableAccount, error) {
+func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
+	outs []*txs.TxOutput, logger *logging.Logger) (map[crypto.Address]acm.MutableAccount, error) {
 	if accs == nil {
-		accs = make(map[acm.Address]acm.MutableAccount)
+		accs = make(map[crypto.Address]acm.MutableAccount)
 	}
 
 	// we should err if an account is being created but the inputs don't have permission
@@ -1093,8 +1094,8 @@ func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[acm.Address]ac
 // If it does then we will associate the public key with the stub account already registered in the system once and
 // for all time.
 func checkInputPubKey(acc acm.MutableAccount, in *txs.TxInput) error {
-	if acc.PublicKey().Unwrap() == nil {
-		if in.PublicKey.Unwrap() == nil {
+	if !acc.PublicKey().IsValid() {
+		if !in.PublicKey.IsValid() {
 			return txs.ErrTxUnknownPubKey
 		}
 		addressFromPubKey := in.PublicKey.Address()
@@ -1104,12 +1105,12 @@ func checkInputPubKey(acc acm.MutableAccount, in *txs.TxInput) error {
 		}
 		acc.SetPublicKey(in.PublicKey)
 	} else {
-		in.PublicKey = acm.PublicKey{}
+		in.PublicKey = crypto.PublicKey{}
 	}
 	return nil
 }
 
-func validateInputs(accs map[acm.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (uint64, error) {
+func validateInputs(accs map[crypto.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (uint64, error) {
 	total := uint64(0)
 	for _, in := range ins {
 		acc := accs[in.Address]
@@ -1132,7 +1133,7 @@ func validateInput(acc acm.MutableAccount, signBytes []byte, in *txs.TxInput) er
 		return err
 	}
 	// Check signatures
-	if !acc.PublicKey().VerifyBytes(signBytes, in.Signature) {
+	if !acc.PublicKey().Verify(signBytes, in.Signature) {
 		return txs.ErrTxInvalidSignature
 	}
 	// Check sequences
@@ -1162,7 +1163,7 @@ func validateOutputs(outs []*txs.TxOutput) (uint64, error) {
 	return total, nil
 }
 
-func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput, logger *logging.Logger) error {
+func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*txs.TxInput, logger *logging.Logger) error {
 	for _, in := range ins {
 		acc := accs[in.Address]
 		if acc == nil {
@@ -1187,7 +1188,7 @@ func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput,
 	return nil
 }
 
-func adjustByOutputs(accs map[acm.Address]acm.MutableAccount, outs []*txs.TxOutput) error {
+func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*txs.TxOutput) error {
 	for _, out := range outs {
 		acc := accs[out.Address]
 		if acc == nil {
@@ -1237,7 +1238,7 @@ func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptyp
 }
 
 // TODO: for debug log the failed accounts
-func hasSendPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount,
+func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
 		if !HasPermission(accountGetter, acc, permission.Send, logger) {
@@ -1262,7 +1263,7 @@ func hasCreateContractPermission(accountGetter state.AccountGetter, acc acm.Acco
 	return HasPermission(accountGetter, acc, permission.CreateContract, logger)
 }
 
-func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.MutableAccount,
+func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
 		if !HasPermission(accountGetter, acc, permission.CreateAccount, logger) {
@@ -1277,7 +1278,7 @@ func hasBondPermission(accountGetter state.AccountGetter, acc acm.Account,
 	return HasPermission(accountGetter, acc, permission.Bond, logger)
 }
 
-func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[acm.Address]acm.Account,
+func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.Account,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
 		if !HasPermission(accountGetter, acc, permission.Bond, logger) {
diff --git a/execution/execution_test.go b/execution/execution_test.go
index b5ff92b288f58b3f132ffd17a007eeff62712c1d..41c1d1cb78ce7cf822fe5b907d0d58da419c69b9 100644
--- a/execution/execution_test.go
+++ b/execution/execution_test.go
@@ -26,6 +26,7 @@ import (
 	"github.com/hyperledger/burrow/account/state"
 	. "github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	exe_events "github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/evm"
@@ -408,7 +409,7 @@ func TestCallPermission(t *testing.T) {
 	fmt.Println("\n##### SIMPLE CONTRACT")
 
 	// create simple contract
-	simpleContractAddr := acm.NewContractAddress(users[0].Address(), 100)
+	simpleContractAddr := crypto.NewContractAddress(users[0].Address(), 100)
 	simpleAcc := acm.ConcreteAccount{
 		Address:     simpleContractAddr,
 		Balance:     0,
@@ -432,7 +433,7 @@ func TestCallPermission(t *testing.T) {
 
 	// create contract that calls the simple contract
 	contractCode := callContractCode(simpleContractAddr)
-	caller1ContractAddr := acm.NewContractAddress(users[0].Address(), 101)
+	caller1ContractAddr := crypto.NewContractAddress(users[0].Address(), 101)
 	caller1Acc := acm.ConcreteAccount{
 		Address:     caller1ContractAddr,
 		Balance:     10000,
@@ -476,7 +477,7 @@ func TestCallPermission(t *testing.T) {
 	fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (FAIL)")
 
 	contractCode2 := callContractCode(caller1ContractAddr)
-	caller2ContractAddr := acm.NewContractAddress(users[0].Address(), 102)
+	caller2ContractAddr := crypto.NewContractAddress(users[0].Address(), 102)
 	caller2Acc := acm.ConcreteAccount{
 		Address:     caller2ContractAddr,
 		Balance:     1000,
@@ -542,7 +543,7 @@ func TestCreatePermission(t *testing.T) {
 		t.Fatal("Transaction failed", err)
 	}
 	// ensure the contract is there
-	contractAddr := acm.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
+	contractAddr := crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
 	contractAcc := getAccount(batchCommitter.stateCache, contractAddr)
 	if contractAcc == nil {
 		t.Fatalf("failed to create contract %s", contractAddr)
@@ -567,7 +568,7 @@ func TestCreatePermission(t *testing.T) {
 		t.Fatal("Transaction failed", err)
 	}
 	// ensure the contract is there
-	contractAddr = acm.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
+	contractAddr = crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
 	contractAcc = getAccount(batchCommitter.stateCache, contractAddr)
 	if contractAcc == nil {
 		t.Fatalf("failed to create contract %s", contractAddr)
@@ -607,9 +608,9 @@ func TestCreatePermission(t *testing.T) {
 
 	//--------------------------------
 	fmt.Println("\n##### CALL to empty address")
-	code := callContractCode(acm.Address{})
+	code := callContractCode(crypto.Address{})
 
-	contractAddr = acm.NewContractAddress(users[0].Address(), 110)
+	contractAddr = crypto.NewContractAddress(users[0].Address(), 110)
 	contractAcc = acm.ConcreteAccount{
 		Address:     contractAddr,
 		Balance:     1000,
@@ -626,11 +627,11 @@ func TestCreatePermission(t *testing.T) {
 	tx, _ = txs.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &contractAddr, createCode, 100, 10000, 100)
 	tx.Sign(testChainID, users[0])
 	// we need to subscribe to the Call event to detect the exception
-	_, exception = execTxWaitEvent(t, batchCommitter, tx, evm_events.EventStringAccountCall(acm.Address{})) //
+	_, exception = execTxWaitEvent(t, batchCommitter, tx, evm_events.EventStringAccountCall(crypto.Address{})) //
 	if exception != "" {
 		t.Fatal("unexpected exception", exception)
 	}
-	zeroAcc := getAccount(batchCommitter.stateCache, acm.Address{})
+	zeroAcc := getAccount(batchCommitter.stateCache, crypto.Address{})
 	if len(zeroAcc.Code()) != 0 {
 		t.Fatal("the zero account was given code from a CALL!")
 	}
@@ -736,7 +737,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	// call to contract that calls unknown account - without create_account perm
 	// create contract that calls the simple contract
 	contractCode := callContractCode(users[9].Address())
-	caller1ContractAddr := acm.NewContractAddress(users[4].Address(), 101)
+	caller1ContractAddr := crypto.NewContractAddress(users[4].Address(), 101)
 	caller1Acc := acm.ConcreteAccount{
 		Address:     caller1ContractAddr,
 		Balance:     0,
@@ -775,7 +776,7 @@ func TestCreateAccountPermission(t *testing.T) {
 }
 
 // holla at my boy
-var DougAddress acm.Address
+var DougAddress crypto.Address
 
 func init() {
 	copy(DougAddress[:], ([]byte)("THISISDOUG"))
@@ -1072,7 +1073,7 @@ func TestNameTxs(t *testing.T) {
 		}
 	}
 
-	validateEntry := func(t *testing.T, entry *NameRegEntry, name, data string, addr acm.Address, expires uint64) {
+	validateEntry := func(t *testing.T, entry *NameRegEntry, name, data string, addr crypto.Address, expires uint64) {
 
 		if entry == nil {
 			t.Fatalf("Could not find name %s", name)
@@ -1721,12 +1722,12 @@ func makeGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV
 	return s0, privAccounts
 }
 
-func getAccount(accountGetter state.AccountGetter, address acm.Address) acm.MutableAccount {
+func getAccount(accountGetter state.AccountGetter, address crypto.Address) acm.MutableAccount {
 	acc, _ := state.GetMutableAccount(accountGetter, address)
 	return acc
 }
 
-func addressPtr(account acm.Account) *acm.Address {
+func addressPtr(account acm.Account) *crypto.Address {
 	if account == nil {
 		return nil
 	}
@@ -1775,18 +1776,18 @@ func execTxWaitEvent(t *testing.T, batchCommitter *executor, tx txs.Tx, eventid
 
 // give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission
 func testSNativeCALLExpectFail(t *testing.T, batchCommitter *executor, doug acm.MutableAccount,
-	snativeAddress acm.Address, data []byte) {
+	snativeAddress crypto.Address, data []byte) {
 	testSNativeCALL(t, false, batchCommitter, doug, 0, snativeAddress, data, nil)
 }
 
 // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds
 func testSNativeCALLExpectPass(t *testing.T, batchCommitter *executor, doug acm.MutableAccount, snativePerm ptypes.PermFlag,
-	snativeAddress acm.Address, data []byte, f func([]byte) error) {
+	snativeAddress crypto.Address, data []byte, f func([]byte) error) {
 	testSNativeCALL(t, true, batchCommitter, doug, snativePerm, snativeAddress, data, f)
 }
 
 func testSNativeCALL(t *testing.T, expectPass bool, batchCommitter *executor, doug acm.MutableAccount,
-	snativePerm ptypes.PermFlag, snativeAddress acm.Address, data []byte, f func([]byte) error) {
+	snativePerm ptypes.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) {
 	if expectPass {
 		doug.MutablePermissions().Base.Set(snativePerm, true)
 	}
@@ -1868,7 +1869,7 @@ func permNameToFuncID(name string) []byte {
 }
 
 func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptypes.PermFlag,
-	val bool) (addr acm.Address, pF ptypes.PermFlag, data []byte) {
+	val bool) (addr crypto.Address, pF ptypes.PermFlag, data []byte) {
 	addr = permissionsContract.Address()
 	switch name {
 	case "hasBase", "unsetBase":
@@ -1907,7 +1908,7 @@ func snativePermTestInputTx(name string, user acm.AddressableSigner, perm ptypes
 }
 
 func snativeRoleTestInputCALL(name string, user acm.AddressableSigner,
-	role string) (addr acm.Address, pF ptypes.PermFlag, data []byte) {
+	role string) (addr crypto.Address, pF ptypes.PermFlag, data []byte) {
 	addr = permissionsContract.Address()
 	data = user.Address().Word256().Bytes()
 	data = append(data, RightPadBytes([]byte(role), 32)...)
@@ -1933,7 +1934,7 @@ func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string
 }
 
 // convenience function for contract that calls a given address
-func callContractCode(contractAddr acm.Address) []byte {
+func callContractCode(contractAddr crypto.Address) []byte {
 	// calldatacopy into mem and use as input to call
 	memOff, inputOff := byte(0x0), byte(0x0)
 	value := byte(0x1)
diff --git a/execution/namereg.go b/execution/namereg.go
index 50babf2a15b60ae8f6d9143cbc3284c1bed9afd8..0c57b351c540e019ae6ab2f68d7e61bb8c5f650c 100644
--- a/execution/namereg.go
+++ b/execution/namereg.go
@@ -14,7 +14,7 @@
 
 package execution
 
-import "github.com/hyperledger/burrow/account"
+import "github.com/hyperledger/burrow/crypto"
 
 // NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an
 // account.
@@ -22,7 +22,7 @@ type NameRegEntry struct {
 	// registered name for the entry
 	Name string
 	// address that created the entry
-	Owner account.Address
+	Owner crypto.Address
 	// data to store under this name
 	Data string
 	// block at which this entry expires
diff --git a/execution/state.go b/execution/state.go
index 8c9b739e36da0fecdb7e2efa9be58987f982c47a..1521faad675e176da33f16e62525217afff2bf78 100644
--- a/execution/state.go
+++ b/execution/state.go
@@ -24,6 +24,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
 	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/logging"
 	ptypes "github.com/hyperledger/burrow/permission"
@@ -176,7 +177,7 @@ func (s *State) Hash() []byte {
 }
 
 // Returns nil if account does not exist with given address.
-func (s *State) GetAccount(address acm.Address) (acm.Account, error) {
+func (s *State) GetAccount(address crypto.Address) (acm.Account, error) {
 	s.RLock()
 	defer s.RUnlock()
 	_, accBytes := s.tree.Get(prefixedKey(accountsPrefix, address.Bytes()))
@@ -204,7 +205,7 @@ func (s *State) UpdateAccount(account acm.Account) error {
 	return nil
 }
 
-func (s *State) RemoveAccount(address acm.Address) error {
+func (s *State) RemoveAccount(address crypto.Address) error {
 	s.Lock()
 	defer s.Unlock()
 	s.tree.Remove(prefixedKey(accountsPrefix, address.Bytes()))
@@ -225,14 +226,14 @@ func (s *State) IterateAccounts(consumer func(acm.Account) (stop bool)) (stopped
 	return
 }
 
-func (s *State) GetStorage(address acm.Address, key binary.Word256) (binary.Word256, error) {
+func (s *State) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) {
 	s.RLock()
 	defer s.RUnlock()
 	_, value := s.tree.Get(prefixedKey(storagePrefix, address.Bytes(), key.Bytes()))
 	return binary.LeftPadWord256(value), nil
 }
 
-func (s *State) SetStorage(address acm.Address, key, value binary.Word256) error {
+func (s *State) SetStorage(address crypto.Address, key, value binary.Word256) error {
 	s.Lock()
 	defer s.Unlock()
 	if value == binary.Zero256 {
@@ -243,7 +244,7 @@ func (s *State) SetStorage(address acm.Address, key, value binary.Word256) error
 	return nil
 }
 
-func (s *State) IterateStorage(address acm.Address,
+func (s *State) IterateStorage(address crypto.Address,
 	consumer func(key, value binary.Word256) (stop bool)) (stopped bool, err error) {
 	s.RLock()
 	defer s.RUnlock()
diff --git a/execution/transactor.go b/execution/transactor.go
index d6e2206d3a8dcf40e220d8a7dd6a777cea4eb665..96f90c2d260a192bb81f9a1f88548ae48b2c16e7 100644
--- a/execution/transactor.go
+++ b/execution/transactor.go
@@ -27,6 +27,7 @@ import (
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/codes"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	exe_events "github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/evm"
@@ -67,7 +68,7 @@ func NewTransactor(tip blockchain.Tip, eventEmitter event.Emitter,
 
 // Run a contract's code on an isolated and unpersisted state
 // Cannot be used to create new contracts
-func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress acm.Address,
+func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress crypto.Address,
 	data []byte) (call *Call, err error) {
 
 	if evm.RegisteredNativeContract(toAddress.Word256()) {
@@ -106,7 +107,7 @@ func (trans *Transactor) Call(reader state.Reader, fromAddress, toAddress acm.Ad
 
 // Run the given code on an isolated and unpersisted state
 // Cannot be used to create new contracts.
-func (trans *Transactor) CallCode(reader state.Reader, fromAddress acm.Address, code, data []byte) (*Call, error) {
+func (trans *Transactor) CallCode(reader state.Reader, fromAddress crypto.Address, code, data []byte) (*Call, error) {
 	// This was being run against CheckTx cache, need to understand the reasoning
 	callee := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
 	caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
@@ -162,7 +163,7 @@ func (trans *Transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) {
 }
 
 // Orders calls to BroadcastTx using lock (waits for response from core before releasing)
-func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *acm.Address, data []byte,
+func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte,
 	gasLimit, fee uint64) (*txs.Receipt, error) {
 
 	// Use the get the freshest sequence numbers from mempool state and hold the lock until we get a response from
@@ -185,7 +186,7 @@ func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAcc
 	return trans.BroadcastTx(callTx)
 }
 
-func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSigningAccount, address *acm.Address, data []byte, gasLimit,
+func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte, gasLimit,
 	fee uint64) (*evm_events.EventDataCall, error) {
 
 	inputAccount, unlock, err := sequentialSigningAccount.Lock()
@@ -239,7 +240,7 @@ func (trans *Transactor) TransactAndHold(sequentialSigningAccount *SequentialSig
 		}
 	}
 }
-func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *acm.Address, data []byte,
+func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *crypto.Address, data []byte,
 	gasLimit, fee uint64) (*txs.CallTx, *txs.Receipt, error) {
 
 	txInput := &txs.TxInput{
@@ -265,7 +266,7 @@ func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *
 	return tx, &receipt, nil
 }
 
-func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress acm.Address,
+func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address,
 	amount uint64) (*txs.Receipt, error) {
 
 	inputAccount, unlock, err := sequentialSigningAccount.Lock()
@@ -282,7 +283,7 @@ func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount
 	return trans.BroadcastTx(sendTx)
 }
 
-func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigningAccount, toAddress acm.Address,
+func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address,
 	amount uint64) (*txs.Receipt, error) {
 
 	inputAccount, unlock, err := sequentialSigningAccount.Lock()
@@ -334,7 +335,7 @@ func (trans *Transactor) SendAndHold(sequentialSigningAccount *SequentialSigning
 	}
 }
 
-func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress acm.Address,
+func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress crypto.Address,
 	amount uint64) (*txs.SendTx, *txs.Receipt, error) {
 
 	sendTx := txs.NewSendTx()
diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go
index de80e258883a9598a7ab32ce5310952d6d9ad95b..ca023f2617dad40d527ec32e078b7718618f6531 100644
--- a/genesis/deterministic_genesis.go
+++ b/genesis/deterministic_genesis.go
@@ -6,6 +6,7 @@ import (
 	"time"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
 )
 
@@ -66,14 +67,14 @@ func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, mi
 }
 
 func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (acm.Account, acm.AddressableSigner) {
-	privateKey, err := acm.GeneratePrivateKey(dg.random)
+	privateKey, err := crypto.GeneratePrivateKey(dg.random, crypto.CurveTypeEd25519)
 	if err != nil {
 		panic(fmt.Errorf("could not generate private key deterministically"))
 	}
 	privAccount := &acm.ConcretePrivateAccount{
-		PublicKey:  privateKey.PublicKey(),
+		PublicKey:  privateKey.GetPublicKey(),
 		PrivateKey: privateKey,
-		Address:    privateKey.PublicKey().Address(),
+		Address:    privateKey.GetPublicKey().Address(),
 	}
 	perms := permission.DefaultAccountPermissions
 	acc := &acm.ConcreteAccount{
diff --git a/genesis/genesis.go b/genesis/genesis.go
index 1c4d0341b49eb295ecf08180b43359a355afda03..16edbe3303664304af5148d25cdffed1554c7810 100644
--- a/genesis/genesis.go
+++ b/genesis/genesis.go
@@ -22,6 +22,7 @@ import (
 	"time"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 )
@@ -36,8 +37,8 @@ const ShortHashSuffixBytes = 3
 
 type BasicAccount struct {
 	// Address  is convenient to have in file for reference, but otherwise ignored since derived from PublicKey
-	Address   acm.Address
-	PublicKey acm.PublicKey
+	Address   crypto.Address
+	PublicKey crypto.PublicKey
 	Amount    uint64
 }
 
diff --git a/genesis/spec/genesis_spec.go b/genesis/spec/genesis_spec.go
index 343b7eaf6d6072ce8caf1d3a4f892cc0a83b22cb..48d8443a968d3385abb6278f9ce5e2e71dd96477 100644
--- a/genesis/spec/genesis_spec.go
+++ b/genesis/spec/genesis_spec.go
@@ -7,7 +7,7 @@ import (
 	"fmt"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/permission"
@@ -35,13 +35,12 @@ type TemplateAccount struct {
 	// Template accounts sharing a name will be merged when merging genesis specs
 	Name string `json:",omitempty" toml:",omitempty"`
 	// Address  is convenient to have in file for reference, but otherwise ignored since derived from PublicKey
-	Address   *acm.Address   `json:",omitempty" toml:",omitempty"`
-	PublicKey *acm.PublicKey `json:",omitempty" toml:",omitempty"`
-	Amount    *uint64        `json:",omitempty" toml:",omitempty"`
-	// If any bonded amount then this account is also a Validator
-	AmountBonded *uint64  `json:",omitempty" toml:",omitempty"`
-	Permissions  []string `json:",omitempty" toml:",omitempty"`
-	Roles        []string `json:",omitempty" toml:",omitempty"`
+	Address      *crypto.Address   `json:",omitempty" toml:",omitempty"`
+	PublicKey    *crypto.PublicKey `json:",omitempty" toml:",omitempty"`
+	Amount       *uint64           `json:",omitempty" toml:",omitempty"`
+	AmountBonded *uint64           `json:",omitempty" toml:",omitempty"`
+	Permissions  []string          `json:",omitempty" toml:",omitempty"`
+	Roles        []string          `json:",omitempty" toml:",omitempty"`
 }
 
 func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int) (*genesis.Validator, error) {
@@ -111,11 +110,11 @@ func (ta TemplateAccount) Account(keyClient keys.KeyClient, index int) (*genesis
 
 // Adds a public key and address to the template. If PublicKey will try to fetch it by Address.
 // If both PublicKey and Address are not set will use the keyClient to generate a new keypair
-func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pubKey acm.PublicKey, address acm.Address, err error) {
+func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pubKey crypto.PublicKey, address crypto.Address, err error) {
 	if ta.PublicKey == nil {
 		if ta.Address == nil {
 			// If neither PublicKey or Address set then generate a new one
-			address, err = keyClient.Generate(ta.Name, keys.KeyTypeEd25519Ripemd160)
+			address, err = keyClient.Generate(ta.Name, crypto.CurveTypeEd25519)
 			if err != nil {
 				return
 			}
@@ -128,7 +127,7 @@ func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pub
 			return
 		}
 	} else {
-		address = ta.PublicKey.Address()
+		address = (*ta.PublicKey).Address()
 		if ta.Address != nil && *ta.Address != address {
 			err = fmt.Errorf("template address %s does not match public key derived address %s", ta.Address,
 				ta.PublicKey)
diff --git a/genesis/spec/genesis_spec_test.go b/genesis/spec/genesis_spec_test.go
index 294c4ed315e600d9907ecd7d749c979d9eac1896..ca91146fb71be6356ffd55abd31cec4590fc0b0b 100644
--- a/genesis/spec/genesis_spec_test.go
+++ b/genesis/spec/genesis_spec_test.go
@@ -3,7 +3,7 @@ package spec
 import (
 	"testing"
 
-	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys/mock"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
@@ -33,7 +33,7 @@ func TestGenesisSpec_GenesisDoc(t *testing.T) {
 	assert.Equal(t, amtBonded, genesisDoc.Validators[0].Amount)
 	assert.NotEmpty(t, genesisDoc.ChainName, "Chain name should not be empty")
 
-	address, err := keyClient.Generate("test-lookup-of-key", keys.KeyTypeEd25519Ripemd160)
+	address, err := keyClient.Generate("test-lookup-of-key", crypto.CurveTypeEd25519)
 	require.NoError(t, err)
 	pubKey, err := keyClient.PublicKey(address)
 	require.NoError(t, err)
diff --git a/keys/common/paths.go b/keys/common/paths.go
new file mode 100644
index 0000000000000000000000000000000000000000..075800636f3034306f135db7fff728811bace0c5
--- /dev/null
+++ b/keys/common/paths.go
@@ -0,0 +1,38 @@
+package common
+
+import (
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+func HomeDir() string {
+	if runtime.GOOS == "windows" {
+		drive := os.Getenv("HOMEDRIVE")
+		path := os.Getenv("HOMEPATH")
+		if drive == "" || path == "" {
+			return os.Getenv("USERPROFILE")
+		}
+		return drive + path
+	} else {
+		return os.Getenv("HOME")
+	}
+}
+
+func ResolveMonaxRoot() string {
+	var monax string
+	if os.Getenv("MONAX") != "" {
+		monax = os.Getenv("MONAX")
+	} else {
+		if runtime.GOOS == "windows" {
+			home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
+			if home == "" {
+				home = os.Getenv("USERPROFILE")
+			}
+			monax = filepath.Join(home, ".monax")
+		} else {
+			monax = filepath.Join(HomeDir(), ".monax")
+		}
+	}
+	return monax
+}
diff --git a/keys/config.go b/keys/config.go
index 2286cabf282d14f97602bad3b7250b0f03a0bf78..d50d61338f9934dbb9301c36ee6878142e1ac81c 100644
--- a/keys/config.go
+++ b/keys/config.go
@@ -1,12 +1,16 @@
 package keys
 
 type KeysConfig struct {
-	URL string
+	GRPCServiceEnabled bool
+	RemoteAddress      string
+	KeysDirectory      string
 }
 
 func DefaultKeysConfig() *KeysConfig {
 	return &KeysConfig{
 		// Default Monax keys port
-		URL: "http://localhost:4767",
+		GRPCServiceEnabled: true,
+		RemoteAddress:      "",
+		KeysDirectory:      DefaultKeysDir,
 	}
 }
diff --git a/keys/core.go b/keys/core.go
new file mode 100644
index 0000000000000000000000000000000000000000..8642a820b331dc99c5ea8c43f30d99210886d433
--- /dev/null
+++ b/keys/core.go
@@ -0,0 +1,191 @@
+package keys
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+
+	tmint_crypto "github.com/hyperledger/burrow/crypto/helpers"
+	wire "github.com/tendermint/go-wire"
+)
+
+const (
+	DefaultHost     = "localhost"
+	DefaultPort     = "10997"
+	DefaultHashType = "sha256"
+	DefaultKeysDir  = ".keys"
+	TestPort        = "7674"
+)
+
+func returnDataDir(dir string) (string, error) {
+	dir = path.Join(dir, "data")
+	dir, err := filepath.Abs(dir)
+	if err != nil {
+		return "", err
+	}
+	return dir, checkMakeDataDir(dir)
+}
+
+func returnNamesDir(dir string) (string, error) {
+	dir = path.Join(dir, "names")
+	dir, err := filepath.Abs(dir)
+	if err != nil {
+		return "", err
+	}
+	return dir, checkMakeDataDir(dir)
+}
+
+//-----
+
+func NewKeyStore(dir string) KeyStore {
+	return KeyStore{keysDirPath: dir}
+}
+
+//----------------------------------------------------------------
+func writeKey(keyDir string, addr, keyJson []byte) ([]byte, error) {
+	dir, err := returnDataDir(keyDir)
+	if err != nil {
+		return nil, fmt.Errorf("Failed to get keys dir: %v", err)
+	}
+	if err := WriteKeyFile(addr, dir, keyJson); err != nil {
+		return nil, err
+	}
+	return addr, nil
+}
+
+func coreExport(key *Key) ([]byte, error) {
+	type privValidator struct {
+		Address    []byte        `json:"address"`
+		PubKey     []interface{} `json:"pub_key"`
+		PrivKey    []interface{} `json:"priv_key"`
+		LastHeight int           `json:"last_height"`
+		LastRound  int           `json:"last_round"`
+		LastStep   int           `json:"last_step"`
+	}
+
+	pub := key.Pubkey()
+
+	var pubKeyWithType []interface{}
+	var pubKey tmint_crypto.PubKeyEd25519
+	copy(pubKey[:], pub)
+	pubKeyWithType = append(pubKeyWithType, tmint_crypto.PubKeyTypeEd25519)
+	pubKeyWithType = append(pubKeyWithType, pubKey)
+
+	var privKeyWithType []interface{}
+	var privKey tmint_crypto.PrivKeyEd25519
+	copy(privKey[:], key.PrivateKey.RawBytes())
+	privKeyWithType = append(privKeyWithType, tmint_crypto.PrivKeyTypeEd25519)
+	privKeyWithType = append(privKeyWithType, privKey)
+
+	privVal := &privValidator{
+		Address: key.Address[:],
+		PubKey:  pubKeyWithType,
+		PrivKey: privKeyWithType,
+	}
+
+	return wire.JSONBytes(privVal), nil
+}
+
+//----------------------------------------------------------------
+// manage names for keys
+
+func coreNameAdd(keysDir, name, addr string) error {
+	namesDir, err := returnNamesDir(keysDir)
+	if err != nil {
+		return err
+	}
+	dataDir, err := returnDataDir(keysDir)
+	if err != nil {
+		return err
+	}
+	if _, err := os.Stat(path.Join(dataDir, addr+".json")); err != nil {
+		return fmt.Errorf("Unknown key %s", addr)
+	}
+	return ioutil.WriteFile(path.Join(namesDir, name), []byte(addr), 0600)
+}
+
+func coreNameList(keysDir string) (map[string]string, error) {
+	dir, err := returnNamesDir(keysDir)
+	if err != nil {
+		return nil, err
+	}
+	names := make(map[string]string)
+	fs, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	for _, f := range fs {
+		b, err := ioutil.ReadFile(path.Join(dir, f.Name()))
+		if err != nil {
+			return nil, err
+		}
+		names[f.Name()] = string(b)
+	}
+	return names, nil
+}
+
+func coreAddrList(keysDir string) (map[int]string, error) {
+	dir, err := returnDataDir(keysDir)
+	if err != nil {
+		return nil, err
+	}
+	addrs := make(map[int]string)
+	fs, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	for i := 0; i < len(fs); i++ {
+		addrs[i] = fs[i].Name()
+	}
+	return addrs, nil
+}
+
+func coreNameRm(keysDir string, name string) error {
+	dir, err := returnNamesDir(keysDir)
+	if err != nil {
+		return err
+	}
+	return os.Remove(path.Join(dir, name))
+}
+
+func coreNameGet(keysDir, name string) (string, error) {
+	dir, err := returnNamesDir(keysDir)
+	if err != nil {
+		return "", err
+	}
+	b, err := ioutil.ReadFile(path.Join(dir, name))
+	if err != nil {
+		return "", err
+	}
+	return string(b), nil
+}
+
+func checkMakeDataDir(dir string) error {
+	if _, err := os.Stat(dir); err != nil {
+		err = os.MkdirAll(dir, 0700)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// return addr from name or addr
+func getNameAddr(keysDir, name, addr string) (string, error) {
+	if name == "" && addr == "" {
+		return "", fmt.Errorf("at least one of name or addr must be provided")
+	}
+
+	// name takes precedent if both are given
+	var err error
+	if name != "" {
+		addr, err = coreNameGet(keysDir, name)
+		if err != nil {
+			return "", err
+		}
+	}
+	return strings.ToUpper(addr), nil
+}
diff --git a/keys/integration/key_client_test.go b/keys/integration/key_client_test.go
deleted file mode 100644
index 83f5d4b6282521292a2326b1d76ee41599b53d47..0000000000000000000000000000000000000000
--- a/keys/integration/key_client_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// +build integration
-
-// Space above here matters
-package integration
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"testing"
-	"time"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-//var logger, _ = lifecycle.NewStdErrLogger()
-var logger = logging.NewNoopLogger()
-
-const monaxKeysBin = "monax-keys"
-const keysHost = "localhost"
-const keysPort = "56667"
-const keysTimeoutSeconds = 3
-
-var rpcString = fmt.Sprintf("http://%s:%s", keysHost, keysPort)
-
-func TestMain(m *testing.M) {
-	fmt.Fprint(os.Stderr, "Running monax-keys using test main\n")
-	_, err := exec.LookPath(monaxKeysBin)
-	if err != nil {
-		fatalf("could not run keys integration tests because could not find keys binary: %v", err)
-	}
-
-	keysDir, err := ioutil.TempDir("", "key_client_test")
-	if err != nil {
-		fatalf("could not create temp dir: %v", err)
-	}
-	cmd := exec.Command(monaxKeysBin, "server", "--dir", keysDir, "--port", keysPort)
-	err = cmd.Start()
-	if err != nil {
-		fatalf("could not start command: %v", err)
-	}
-
-	select {
-	case <-waitKeysRunning():
-		// A plain call to os.Exit will terminate before deferred calls run, so defer that too.
-		defer os.Exit(m.Run())
-	case <-time.After(keysTimeoutSeconds * time.Second):
-		defer fatalf("timed out waiting for monax-keys to become live")
-	}
-
-	defer func() {
-		err := cmd.Process.Kill()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Error killing monax-keys from test main:%v\n", err)
-		}
-		fmt.Fprint(os.Stderr, "Killed monax-keys from test main\n")
-	}()
-}
-
-func TestMonaxKeyClient_Generate(t *testing.T) {
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160)
-	assert.NoError(t, err)
-	assert.NotEqual(t, acm.ZeroAddress, addr)
-}
-
-func TestMonaxKeyClient_PublicKey(t *testing.T) {
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160)
-	assert.NoError(t, err)
-	pubKey, err := keyClient.PublicKey(addr)
-	assert.Equal(t, addr, pubKey.Address())
-}
-
-func TestMonaxKeyClient_PublicKey_NonExistent(t *testing.T) {
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	_, err := keyClient.PublicKey(acm.Address{8, 7, 6, 222})
-	assert.Error(t, err)
-}
-
-func TestMonaxKeyClient_Sign(t *testing.T) {
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	pubKey, err := keyClient.PublicKey(addr)
-	assert.NoError(t, err)
-	message := []byte("I'm a hat, a hat, a hat")
-	signature, err := keyClient.Sign(addr, message)
-	assert.NoError(t, err)
-	assert.True(t, pubKey.VerifyBytes(message, signature), "signature should verify message")
-}
-
-func TestMonaxKeyClient_HealthCheck(t *testing.T) {
-	deadKeyClient := keys.NewKeyClient("http://localhost:99999", logger)
-	assert.NotNil(t, deadKeyClient.HealthCheck())
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	assert.Nil(t, keyClient.HealthCheck())
-}
-
-func TestPublicKeyAddressAgreement(t *testing.T) {
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	addr, err := keyClient.Generate("I'm a lovely hat", keys.KeyTypeEd25519Ripemd160)
-	require.NoError(t, err)
-	pubKey, err := keyClient.PublicKey(addr)
-	addrOut := pubKey.Address()
-	require.NoError(t, err)
-	assert.Equal(t, addr, addrOut)
-}
-
-func fatalf(format string, a ...interface{}) {
-	fmt.Fprintf(os.Stderr, format, a...)
-	os.Exit(1)
-}
-
-func waitKeysRunning() chan bool {
-	ch := make(chan bool)
-	keyClient := keys.NewKeyClient(rpcString, logger)
-	go func() {
-		for {
-			err := keyClient.HealthCheck()
-			if err == nil {
-				ch <- true
-				return
-			}
-		}
-
-	}()
-	return ch
-}
diff --git a/keys/key_client.go b/keys/key_client.go
index c70cb4aecca9af987937d6f50675c5def19f4bce..49983e41c987427e403b747b41a96cbe5234cb11 100644
--- a/keys/key_client.go
+++ b/keys/key_client.go
@@ -15,71 +15,177 @@
 package keys
 
 import (
-	"encoding/hex"
+	"context"
 	"fmt"
+	"time"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
+	"google.golang.org/grpc"
 )
 
 type KeyClient interface {
 	// Sign returns the signature bytes for given message signed with the key associated with signAddress
-	Sign(signAddress acm.Address, message []byte) (signature acm.Signature, err error)
+	Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error)
 
 	// PublicKey returns the public key associated with a given address
-	PublicKey(address acm.Address) (publicKey acm.PublicKey, err error)
+	PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error)
 
 	// Generate requests that a key be generate within the keys instance and returns the address
-	Generate(keyName string, keyType KeyType) (keyAddress acm.Address, err error)
+	Generate(keyName string, keyType crypto.CurveType) (keyAddress crypto.Address, err error)
 
 	// Returns nil if the keys instance is healthy, error otherwise
 	HealthCheck() error
 }
 
-// This mirrors "github.com/monax/keys/crypto/KeyType" but since we have no use for the struct here it seems simpler
-// to replicate rather than cop an import
-type KeyType string
+var _ KeyClient = (*localKeyClient)(nil)
+var _ KeyClient = (*remoteKeyClient)(nil)
 
-func (kt KeyType) String() string {
-	return string(kt)
+type localKeyClient struct {
+	ks     KeyStore
+	logger *logging.Logger
 }
 
-const (
-	KeyTypeEd25519Ripemd160         KeyType = "ed25519,ripemd160"
-	KeyTypeEd25519Ripemd160sha256           = "ed25519,ripemd160sha256"
-	KeyTypeEd25519Ripemd160sha3             = "ed25519,sha3"
-	KeyTypeSecp256k1Ripemd160               = "secp256k1,ripemd160"
-	KeyTypeSecp256k1Ripemd160sha256         = "secp256k1,ripemd160sha256"
-	KeyTypeSecp256k1Ripemd160sha3           = "secp256k1,sha3"
-	KeyTypeDefault                          = KeyTypeEd25519Ripemd160
-)
+type remoteKeyClient struct {
+	rpcAddress string
+	kc         pbkeys.KeysClient
+	logger     *logging.Logger
+}
+
+func (l localKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) {
+	resp, err := l.ks.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Message: message})
+	if err != nil {
+		return crypto.Signature{}, err
+	}
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	if err != nil {
+		return crypto.Signature{}, err
+	}
+	return crypto.SignatureFromBytes(resp.GetSignature(), curveType)
+}
+
+func (l localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) {
+	resp, err := l.ks.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()})
+	if err != nil {
+		return crypto.PublicKey{}, err
+	}
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	if err != nil {
+		return crypto.PublicKey{}, err
+	}
+	return crypto.PublicKeyFromBytes(resp.GetPub(), curveType)
+}
 
-// NOTE [ben] Compiler check to ensure keyClient successfully implements
-// burrow/keys.KeyClient
-var _ KeyClient = (*keyClient)(nil)
+// Generate requests that a key be generate within the keys instance and returns the address
+func (l localKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) {
+	resp, err := l.ks.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()})
+	if err != nil {
+		return crypto.Address{}, err
+	}
+	return crypto.AddressFromHexString(resp.GetAddress())
+}
 
-type keyClient struct {
-	requester Requester
-	logger    *logging.Logger
+// Returns nil if the keys instance is healthy, error otherwise
+func (l localKeyClient) HealthCheck() error {
+	return nil
 }
 
-type signer struct {
-	keyClient KeyClient
-	address   acm.Address
+func (l remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	req := pbkeys.SignRequest{Address: signAddress.String(), Message: message}
+	l.logger.TraceMsg("Sending Sign request to remote key server: ", fmt.Sprintf("%v", req))
+	resp, err := l.kc.Sign(ctx, &req)
+	if err != nil {
+		l.logger.TraceMsg("Received Sign request error response: ", err)
+		return crypto.Signature{}, err
+	}
+	l.logger.TraceMsg("Received Sign response to remote key server: %v", resp)
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	if err != nil {
+		return crypto.Signature{}, err
+	}
+	return crypto.SignatureFromBytes(resp.GetSignature(), curveType)
+}
+
+func (l remoteKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	req := pbkeys.PubRequest{Address: address.String()}
+	l.logger.TraceMsg("Sending PublicKey request to remote key server: ", fmt.Sprintf("%v", req))
+	resp, err := l.kc.PublicKey(ctx, &req)
+	if err != nil {
+		l.logger.TraceMsg("Received PublicKey error response: ", err)
+		return crypto.PublicKey{}, err
+	}
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	if err != nil {
+		return crypto.PublicKey{}, err
+	}
+	l.logger.TraceMsg("Received PublicKey response to remote key server: ", fmt.Sprintf("%v", resp))
+	return crypto.PublicKeyFromBytes(resp.GetPub(), curveType)
+}
+
+// Generate requests that a key be generate within the keys instance and returns the address
+func (l remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	req := pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}
+	l.logger.TraceMsg("Sending Generate request to remote key server: ", fmt.Sprintf("%v", req))
+	resp, err := l.kc.GenerateKey(ctx, &req)
+	if err != nil {
+		l.logger.TraceMsg("Received Generate error response: ", err)
+		return crypto.Address{}, err
+	}
+	l.logger.TraceMsg("Received Generate response to remote key server: ", fmt.Sprintf("%v", resp))
+	return crypto.AddressFromHexString(resp.GetAddress())
+}
+
+// Returns nil if the keys instance is healthy, error otherwise
+func (l remoteKeyClient) HealthCheck() error {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	_, err := l.kc.List(ctx, &pbkeys.Name{""})
+	return err
 }
 
 // keyClient.New returns a new monax-keys client for provided rpc location
 // Monax-keys connects over http request-responses
-func NewKeyClient(rpcAddress string, logger *logging.Logger) *keyClient {
-	logger = logger.WithScope("NewKeyClient")
-	return &keyClient{
-		requester: DefaultRequester(rpcAddress, logger),
-		logger:    logger,
+func NewRemoteKeyClient(rpcAddress string, logger *logging.Logger) (KeyClient, error) {
+	logger = logger.WithScope("RemoteKeyClient")
+	var opts []grpc.DialOption
+	opts = append(opts, grpc.WithInsecure())
+	conn, err := grpc.Dial(rpcAddress, opts...)
+	if err != nil {
+		return nil, err
 	}
+	kc := pbkeys.NewKeysClient(conn)
+
+	return remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger}, nil
+}
+
+func NewLocalKeyClient(ks KeyStore, logger *logging.Logger) KeyClient {
+	logger = logger.WithScope("LocalKeyClient")
+	return localKeyClient{ks: ks, logger: logger}
+}
+
+type signer struct {
+	keyClient KeyClient
+	address   crypto.Address
+}
+
+func (ms *signer) Sign(messsage []byte) (crypto.Signature, error) {
+	signature, err := ms.keyClient.Sign(ms.address, messsage)
+	if err != nil {
+		return crypto.Signature{}, err
+	}
+	return signature, nil
 }
 
 // Creates a Signer that assumes the address holds an Ed25519 key
-func Signer(keyClient KeyClient, address acm.Address) acm.Signer {
+func Signer(keyClient KeyClient, address crypto.Address) crypto.Signer {
 	// TODO: we can do better than this and return a typed signature when we reform the keys service
 	return &signer{
 		keyClient: keyClient,
@@ -88,19 +194,19 @@ func Signer(keyClient KeyClient, address acm.Address) acm.Signer {
 }
 
 type keyAddressable struct {
-	publicKey acm.PublicKey
-	address   acm.Address
+	publicKey crypto.PublicKey
+	address   crypto.Address
 }
 
-func (ka *keyAddressable) Address() acm.Address {
+func (ka *keyAddressable) Address() crypto.Address {
 	return ka.address
 }
 
-func (ka *keyAddressable) PublicKey() acm.PublicKey {
+func (ka *keyAddressable) PublicKey() crypto.PublicKey {
 	return ka.publicKey
 }
 
-func Addressable(keyClient KeyClient, address acm.Address) (acm.Addressable, error) {
+func Addressable(keyClient KeyClient, address crypto.Address) (acm.Addressable, error) {
 	pubKey, err := keyClient.PublicKey(address)
 	if err != nil {
 		return nil, err
@@ -110,69 +216,3 @@ func Addressable(keyClient KeyClient, address acm.Address) (acm.Addressable, err
 		publicKey: pubKey,
 	}, nil
 }
-
-func (ms *signer) Sign(messsage []byte) (acm.Signature, error) {
-	signature, err := ms.keyClient.Sign(ms.address, messsage)
-	if err != nil {
-		return acm.Signature{}, err
-	}
-	return signature, nil
-}
-
-// Monax-keys client Sign requests the signature from BurrowKeysClient over rpc for the given
-// bytes to be signed and the address to sign them with.
-func (kc *keyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
-	sigS, err := kc.requester("sign", map[string]string{
-		"msg":  hex.EncodeToString(message),
-		"addr": signAddress.String(),
-	})
-	if err != nil {
-		return acm.Signature{}, err
-	}
-	sigBytes, err := hex.DecodeString(sigS)
-	if err != nil {
-		return acm.Signature{}, err
-	}
-	return acm.SignatureFromBytes(sigBytes)
-}
-
-// Monax-keys client PublicKey requests the public key associated with an address from
-// the monax-keys server.
-func (kc *keyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
-	pubS, err := kc.requester("pub", map[string]string{
-		"addr": address.String(),
-	})
-	if err != nil {
-		return acm.PublicKey{}, err
-	}
-	pubKeyBytes, err := hex.DecodeString(pubS)
-	if err != nil {
-		return acm.PublicKey{}, err
-	}
-	publicKey, err := acm.PublicKeyFromBytes(pubKeyBytes)
-	if err != nil {
-		return acm.PublicKey{}, err
-	}
-	if address != publicKey.Address() {
-		return acm.PublicKey{}, fmt.Errorf("public key %s maps to address %s but was returned for address %s",
-			publicKey, publicKey.Address(), address)
-	}
-	return publicKey, nil
-}
-
-func (kc *keyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) {
-	addr, err := kc.requester("gen", map[string]string{
-		//"auth": auth,
-		"name": keyName,
-		"type": keyType.String(),
-	})
-	if err != nil {
-		return acm.ZeroAddress, err
-	}
-	return acm.AddressFromHexString(addr)
-}
-
-func (kc *keyClient) HealthCheck() error {
-	_, err := kc.requester("name/ls", nil)
-	return err
-}
diff --git a/keys/key_client_util.go b/keys/key_client_util.go
deleted file mode 100644
index 89a41a366d359b1fc2cc90377fa20f5c9e004e08..0000000000000000000000000000000000000000
--- a/keys/key_client_util.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package keys
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-
-	"github.com/hyperledger/burrow/logging"
-)
-
-// Monax-Keys server connects over http request-response structures
-
-type HTTPResponse struct {
-	Response string
-	Error    string
-}
-
-type Requester func(method string, args map[string]string) (response string, err error)
-
-func DefaultRequester(rpcAddress string, logger *logging.Logger) Requester {
-	return func(method string, args map[string]string) (string, error) {
-		body, err := json.Marshal(args)
-		if err != nil {
-			return "", err
-		}
-		endpoint := fmt.Sprintf("%s/%s", rpcAddress, method)
-		logger.TraceMsg("Sending request to key server",
-			"key_server_endpoint", endpoint,
-			"request_body", string(body),
-		)
-		req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(body))
-		if err != nil {
-			return "", err
-		}
-		req.Header.Add("Content-Type", "application/json")
-		res, err := requestResponse(req)
-		if err != nil {
-			return "", fmt.Errorf("error calling monax-keys at %s: %s", endpoint, err.Error())
-		}
-		if res.Error != "" {
-			return "", fmt.Errorf("response error when calling monax-keys at %s: %s", endpoint, res.Error)
-		}
-		logger.TraceMsg("Received response from key server",
-			"endpoint", endpoint,
-			"request_body", string(body),
-			"response", res,
-		)
-		return res.Response, nil
-	}
-}
-
-func requestResponse(req *http.Request) (*HTTPResponse, error) {
-	client := new(http.Client)
-	resp, err := client.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	if resp.StatusCode >= 400 {
-		return nil, fmt.Errorf(resp.Status)
-	}
-	bs, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	httpResponse := new(HTTPResponse)
-	if err := json.Unmarshal(bs, httpResponse); err != nil {
-		return nil, err
-	}
-	return httpResponse, nil
-}
diff --git a/keys/key_store.go b/keys/key_store.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe6c3d54ba306ea46a3dc17ebe1141216be17df3
--- /dev/null
+++ b/keys/key_store.go
@@ -0,0 +1,68 @@
+package keys
+
+import (
+	"github.com/hyperledger/burrow/crypto"
+)
+
+type Key struct {
+	CurveType  crypto.CurveType
+	Address    crypto.Address
+	PublicKey  crypto.PublicKey
+	PrivateKey crypto.PrivateKey
+}
+
+func NewKey(typ crypto.CurveType) (*Key, error) {
+	privKey, err := crypto.GeneratePrivateKey(nil, typ)
+	if err != nil {
+		return nil, err
+	}
+	pubKey := privKey.GetPublicKey()
+	return &Key{
+		CurveType:  typ,
+		PublicKey:  pubKey,
+		Address:    pubKey.Address(),
+		PrivateKey: privKey,
+	}, nil
+}
+
+func (k *Key) Pubkey() []byte {
+	return k.PublicKey.RawBytes()
+}
+
+func NewKeyFromPub(curveType crypto.CurveType, PubKeyBytes []byte) (*Key, error) {
+	pubKey, err := crypto.PublicKeyFromBytes(PubKeyBytes, curveType)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Key{
+		CurveType: curveType,
+		PublicKey: pubKey,
+		Address:   pubKey.Address(),
+	}, nil
+}
+
+func NewKeyFromPriv(curveType crypto.CurveType, PrivKeyBytes []byte) (*Key, error) {
+	privKey, err := crypto.PrivateKeyFromRawBytes(PrivKeyBytes, curveType)
+
+	if err != nil {
+		return nil, err
+	}
+
+	pubKey := privKey.GetPublicKey()
+
+	return &Key{
+		CurveType:  curveType,
+		Address:    pubKey.Address(),
+		PublicKey:  pubKey,
+		PrivateKey: privKey,
+	}, nil
+}
+
+func (k *Key) Sign(hash []byte) ([]byte, error) {
+	signature, err := k.PrivateKey.Sign(hash)
+	if err != nil {
+		return nil, err
+	}
+	return signature.RawBytes(), nil
+}
diff --git a/keys/key_store_file.go b/keys/key_store_file.go
new file mode 100644
index 0000000000000000000000000000000000000000..25c2f56728c7c436250bda1837c5b90c81874180
--- /dev/null
+++ b/keys/key_store_file.go
@@ -0,0 +1,336 @@
+package keys
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path"
+	"strings"
+	"sync"
+
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/tmthrgd/go-hex"
+
+	"golang.org/x/crypto/scrypt"
+)
+
+const (
+	scryptN       = 1 << 18
+	scryptr       = 8
+	scryptp       = 1
+	scryptdkLen   = 32
+	CryptoNone    = "none"
+	CryptoAESGCM  = "scrypt-aes-gcm"
+	HashEd25519   = "go-crypto-0.5.0"
+	HashSecp256k1 = "btc"
+)
+
+//-----------------------------------------------------------------------------
+// json encodings
+
+// addresses should be hex encoded
+
+type keyJSON struct {
+	CurveType   string
+	Address     string
+	PublicKey   []byte
+	AddressHash string
+	PrivateKey  privateKeyJSON
+}
+
+type privateKeyJSON struct {
+	Crypto     string
+	Plain      []byte `json:",omitempty"`
+	Salt       []byte `json:",omitempty"`
+	Nonce      []byte `json:",omitempty"`
+	CipherText []byte `json:",omitempty"`
+}
+
+func (k *Key) MarshalJSON() (j []byte, err error) {
+	jStruct := keyJSON{
+		CurveType:   k.CurveType.String(),
+		Address:     hex.EncodeToString(k.Address[:]),
+		PublicKey:   k.Pubkey(),
+		AddressHash: k.PublicKey.AddressHashType(),
+		PrivateKey:  privateKeyJSON{Crypto: CryptoNone, Plain: k.PrivateKey.RawBytes()},
+	}
+	j, err = json.Marshal(jStruct)
+	return j, err
+}
+
+func (k *Key) UnmarshalJSON(j []byte) (err error) {
+	keyJ := new(keyJSON)
+	err = json.Unmarshal(j, &keyJ)
+	if err != nil {
+		return err
+	}
+	if len(keyJ.PrivateKey.Plain) == 0 {
+		return fmt.Errorf("no private key")
+	}
+	curveType, err := crypto.CurveTypeFromString(keyJ.CurveType)
+	if err != nil {
+		curveType = crypto.CurveTypeEd25519
+	}
+	k2, err := NewKeyFromPriv(curveType, keyJ.PrivateKey.Plain)
+	if err != nil {
+		return err
+	}
+
+	k.Address = k2.Address
+	k.CurveType = curveType
+	k.PublicKey = k2.PrivateKey.GetPublicKey()
+	k.PrivateKey = k2.PrivateKey
+
+	return nil
+}
+
+// returns the address if valid, nil otherwise
+func IsValidKeyJson(j []byte) []byte {
+	j1 := new(keyJSON)
+	e1 := json.Unmarshal(j, &j1)
+	if e1 == nil {
+		addr, _ := hex.DecodeString(j1.Address)
+		return addr
+	}
+	return nil
+}
+
+type KeyStore struct {
+	sync.Mutex
+	keysDirPath string
+}
+
+func (ks KeyStore) Gen(passphrase string, curveType crypto.CurveType) (key *Key, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("GenerateNewKey error: %v", r)
+		}
+	}()
+	key, err = NewKey(curveType)
+	if err != nil {
+		return nil, err
+	}
+	err = ks.StoreKey(passphrase, key)
+	return key, err
+}
+
+func (ks KeyStore) GetKey(passphrase string, keyAddr []byte) (*Key, error) {
+	ks.Lock()
+	defer ks.Unlock()
+	dataDirPath, err := returnDataDir(ks.keysDirPath)
+	if err != nil {
+		return nil, err
+	}
+	fileContent, err := GetKeyFile(dataDirPath, keyAddr)
+	if err != nil {
+		return nil, err
+	}
+	key := new(keyJSON)
+	if err = json.Unmarshal(fileContent, key); err != nil {
+		return nil, err
+	}
+
+	if len(key.PrivateKey.CipherText) > 0 {
+		return DecryptKey(passphrase, key)
+	} else {
+		key := new(Key)
+		err = key.UnmarshalJSON(fileContent)
+		return key, err
+	}
+}
+
+func (ks KeyStore) AllKeys() ([]*Key, error) {
+
+	dataDirPath, err := returnDataDir(ks.keysDirPath)
+	if err != nil {
+		return nil, err
+	}
+	addrs, err := GetAllAddresses(dataDirPath)
+	if err != nil {
+		return nil, err
+	}
+
+	var list []*Key
+
+	for _, addr := range addrs {
+		k, err := ks.GetKey("", addr)
+		if err != nil {
+			return nil, err
+		}
+		list = append(list, k)
+	}
+
+	return list, nil
+}
+
+func DecryptKey(passphrase string, keyProtected *keyJSON) (*Key, error) {
+	salt := keyProtected.PrivateKey.Salt
+	nonce := keyProtected.PrivateKey.Nonce
+	cipherText := keyProtected.PrivateKey.CipherText
+
+	curveType, err := crypto.CurveTypeFromString(keyProtected.CurveType)
+	if err != nil {
+		return nil, err
+	}
+	authArray := []byte(passphrase)
+	derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen)
+	if err != nil {
+		return nil, err
+	}
+	aesBlock, err := aes.NewCipher(derivedKey)
+	if err != nil {
+		return nil, err
+	}
+	gcm, err := cipher.NewGCM(aesBlock)
+	if err != nil {
+		return nil, err
+	}
+	plainText, err := gcm.Open(nil, nonce, cipherText, nil)
+	if err != nil {
+		pkey, _ := NewKeyFromPub(curveType, keyProtected.PublicKey)
+		return pkey, err
+	}
+	address, err := crypto.AddressFromHexString(keyProtected.Address)
+	if err != nil {
+		return nil, err
+	}
+	k, err := NewKeyFromPriv(curveType, plainText)
+	if err != nil {
+		return nil, err
+	}
+	if address != k.Address {
+		return nil, fmt.Errorf("address does not match")
+	}
+	return k, nil
+}
+
+func (ks KeyStore) GetAllAddresses() (addresses [][]byte, err error) {
+	ks.Lock()
+	defer ks.Unlock()
+	return GetAllAddresses(ks.keysDirPath)
+}
+
+func (ks KeyStore) StoreKey(passphrase string, key *Key) error {
+	ks.Lock()
+	defer ks.Unlock()
+	if passphrase != "" {
+		return ks.StoreKeyEncrypted(passphrase, key)
+	} else {
+		return ks.StoreKeyPlain(key)
+	}
+}
+
+func (ks KeyStore) StoreKeyPlain(key *Key) (err error) {
+	keyJSON, err := json.Marshal(key)
+	if err != nil {
+		return err
+	}
+	dataDirPath, err := returnDataDir(ks.keysDirPath)
+	if err != nil {
+		return err
+	}
+	err = WriteKeyFile(key.Address[:], dataDirPath, keyJSON)
+	return err
+}
+
+func (ks KeyStore) StoreKeyEncrypted(passphrase string, key *Key) error {
+	authArray := []byte(passphrase)
+	salt := make([]byte, 32)
+	_, err := rand.Read(salt)
+	if err != nil {
+		return err
+	}
+
+	derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen)
+	if err != nil {
+		return err
+	}
+
+	toEncrypt := key.PrivateKey.RawBytes()
+
+	AES256Block, err := aes.NewCipher(derivedKey)
+	if err != nil {
+		return err
+	}
+
+	gcm, err := cipher.NewGCM(AES256Block)
+	if err != nil {
+		return err
+	}
+
+	// XXX: a GCM nonce may only be used once per key ever!
+	nonce := make([]byte, gcm.NonceSize())
+	_, err = rand.Read(nonce)
+	if err != nil {
+		return err
+	}
+
+	// (dst, nonce, plaintext, extradata)
+	cipherText := gcm.Seal(nil, nonce, toEncrypt, nil)
+
+	cipherStruct := privateKeyJSON{
+		Crypto: CryptoAESGCM, Salt: salt, Nonce: nonce, CipherText: cipherText,
+	}
+	keyStruct := keyJSON{
+		CurveType:   key.CurveType.String(),
+		Address:     strings.ToUpper(hex.EncodeToString(key.Address[:])),
+		PublicKey:   key.Pubkey(),
+		AddressHash: key.PublicKey.AddressHashType(),
+		PrivateKey:  cipherStruct,
+	}
+	keyJSON, err := json.Marshal(keyStruct)
+	if err != nil {
+		return err
+	}
+	dataDirPath, err := returnDataDir(ks.keysDirPath)
+	if err != nil {
+		return err
+	}
+
+	return WriteKeyFile(key.Address[:], dataDirPath, keyJSON)
+}
+
+func (ks KeyStore) DeleteKey(passphrase string, keyAddr []byte) (err error) {
+	dataDirPath, err := returnDataDir(ks.keysDirPath)
+	if err != nil {
+		return err
+	}
+	keyDirPath := path.Join(dataDirPath, strings.ToUpper(hex.EncodeToString(keyAddr))+".json")
+	return os.Remove(keyDirPath)
+}
+
+func GetKeyFile(dataDirPath string, keyAddr []byte) (fileContent []byte, err error) {
+	fileName := strings.ToUpper(hex.EncodeToString(keyAddr))
+	return ioutil.ReadFile(path.Join(dataDirPath, fileName+".json"))
+}
+
+func WriteKeyFile(addr []byte, dataDirPath string, content []byte) (err error) {
+	addrHex := strings.ToUpper(hex.EncodeToString(addr))
+	keyFilePath := path.Join(dataDirPath, addrHex+".json")
+	err = os.MkdirAll(dataDirPath, 0700) // read, write and dir search for user
+	if err != nil {
+		return err
+	}
+	return ioutil.WriteFile(keyFilePath, content, 0600) // read, write for user
+}
+
+func GetAllAddresses(dataDirPath string) (addresses [][]byte, err error) {
+	fileInfos, err := ioutil.ReadDir(dataDirPath)
+	if err != nil {
+		return nil, err
+	}
+	addresses = make([][]byte, len(fileInfos))
+	for i, fileInfo := range fileInfos {
+		addr := strings.TrimSuffix(fileInfo.Name(), "json")
+		address, err := hex.DecodeString(addr)
+		if err != nil {
+			continue
+		}
+		addresses[i] = address
+	}
+	return addresses, err
+}
diff --git a/keys/mock/key.go b/keys/mock/key.go
index 8000bf28cd43e462cb6f6b0395c36bcd5e015eab..83a7f0010aedd4c4646956b3bd5c6d1060425b73 100644
--- a/keys/mock/key.go
+++ b/keys/mock/key.go
@@ -6,10 +6,9 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/crypto"
+
 	"github.com/pkg/errors"
-	"github.com/tendermint/go-crypto"
-	"github.com/wayn3h0/go-uuid"
 	"golang.org/x/crypto/ed25519"
 )
 
@@ -17,7 +16,7 @@ import (
 // Simple ed25519 key structure for mock purposes with ripemd160 address
 type Key struct {
 	Name       string
-	Address    acm.Address
+	Address    crypto.Address
 	PublicKey  []byte
 	PrivateKey []byte
 }
@@ -37,10 +36,12 @@ func newKey(name string) (*Key, error) {
 	copy(key.PrivateKey[:], privateKey[:])
 	copy(key.PublicKey[:], publicKey[:])
 
-	var ed25519 crypto.PubKeyEd25519
-	copy(ed25519[:], publicKey[:])
+	pk, err := crypto.PublicKeyFromBytes(publicKey, crypto.CurveTypeEd25519)
+	if err != nil {
+		return nil, err
+	}
 
-	key.Address, err = acm.AddressFromBytes(ed25519.Address())
+	key.Address, err = crypto.AddressFromBytes(pk.Address().Bytes())
 	if err != nil {
 		return nil, err
 	}
@@ -55,8 +56,7 @@ func newKey(name string) (*Key, error) {
 }
 
 func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key {
-	_, ok := privateAccount.PrivateKey().Unwrap().(crypto.PrivKeyEd25519)
-	if !ok {
+	if privateAccount.PrivateKey().CurveType != crypto.CurveTypeEd25519 {
 		panic(fmt.Errorf("mock key client only supports ed25519 private keys at present"))
 	}
 	key := &Key{
@@ -68,29 +68,27 @@ func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key {
 	return key
 }
 
-func (key *Key) Sign(message []byte) (acm.Signature, error) {
-	return acm.SignatureFromBytes(ed25519.Sign(key.PrivateKey, message))
+func (key *Key) Sign(message []byte) (crypto.Signature, error) {
+	return crypto.SignatureFromBytes(ed25519.Sign(key.PrivateKey, message), crypto.CurveTypeEd25519)
+}
+
+type PrivateKeyplainKeyJSON struct {
+	Plain []byte
 }
 
 // TODO: remove after merging keys taken from there to match serialisation
 type plainKeyJSON struct {
-	Id         []byte
 	Type       string
 	Address    string
-	PrivateKey []byte
+	PrivateKey PrivateKeyplainKeyJSON
 }
 
 // Returns JSON string compatible with that stored by monax-keys
 func (key *Key) MonaxKeysJSON() string {
-	id, err := uuid.NewRandom()
-	if err != nil {
-		return errors.Wrap(err, "could not create monax key json").Error()
-	}
 	jsonKey := plainKeyJSON{
-		Id:         []byte(id.String()),
 		Address:    key.Address.String(),
-		Type:       string(keys.KeyTypeEd25519Ripemd160),
-		PrivateKey: key.PrivateKey,
+		Type:       "ed25519",
+		PrivateKey: PrivateKeyplainKeyJSON{Plain: key.PrivateKey},
 	}
 	bs, err := json.Marshal(jsonKey)
 	if err != nil {
diff --git a/keys/mock/key_client.go b/keys/mock/key_client.go
index 821c0c82499cb970a5f796497879e8281d9c8cc7..a9c646704cc466b027e0ec344a0962117ec7a410 100644
--- a/keys/mock/key_client.go
+++ b/keys/mock/key_client.go
@@ -18,8 +18,8 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
-	"github.com/tendermint/go-crypto"
 )
 
 //---------------------------------------------------------------------
@@ -29,12 +29,12 @@ import (
 var _ keys.KeyClient = (*KeyClient)(nil)
 
 type KeyClient struct {
-	knownKeys map[acm.Address]*Key
+	knownKeys map[crypto.Address]*Key
 }
 
 func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient {
 	client := &KeyClient{
-		knownKeys: make(map[acm.Address]*Key),
+		knownKeys: make(map[crypto.Address]*Key),
 	}
 	for _, pa := range privateAccounts {
 		client.knownKeys[pa.Address()] = mockKeyFromPrivateAccount(pa)
@@ -42,7 +42,7 @@ func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient {
 	return client
 }
 
-func (mkc *KeyClient) NewKey(name string) acm.Address {
+func (mkc *KeyClient) NewKey(name string) crypto.Address {
 	// Only tests ED25519 curve and ripemd160.
 	key, err := newKey(name)
 	if err != nil {
@@ -52,25 +52,23 @@ func (mkc *KeyClient) NewKey(name string) acm.Address {
 	return key.Address
 }
 
-func (mkc *KeyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
+func (mkc *KeyClient) Sign(signAddress crypto.Address, message []byte) (crypto.Signature, error) {
 	key := mkc.knownKeys[signAddress]
 	if key == nil {
-		return acm.Signature{}, fmt.Errorf("unknown address (%s)", signAddress)
+		return crypto.Signature{}, fmt.Errorf("unknown address (%s)", signAddress)
 	}
 	return key.Sign(message)
 }
 
-func (mkc *KeyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
+func (mkc *KeyClient) PublicKey(address crypto.Address) (crypto.PublicKey, error) {
 	key := mkc.knownKeys[address]
 	if key == nil {
-		return acm.PublicKey{}, fmt.Errorf("unknown address (%s)", address)
+		return crypto.PublicKey{}, fmt.Errorf("unknown address (%s)", address)
 	}
-	pubKeyEd25519 := crypto.PubKeyEd25519{}
-	copy(pubKeyEd25519[:], key.PublicKey)
-	return acm.PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap())
+	return crypto.PublicKeyFromBytes(key.PublicKey, crypto.CurveTypeEd25519)
 }
 
-func (mkc *KeyClient) Generate(keyName string, keyType keys.KeyType) (acm.Address, error) {
+func (mkc *KeyClient) Generate(keyName string, curve crypto.CurveType) (crypto.Address, error) {
 	return mkc.NewKey(keyName), nil
 }
 
diff --git a/keys/mock/key_client_test.go b/keys/mock/key_client_test.go
index 7f74a03733c54f751bcecab7fa6abfe691dbeebf..72dc557e7fe05439a39af3e6604b5fd5a5650ecc 100644
--- a/keys/mock/key_client_test.go
+++ b/keys/mock/key_client_test.go
@@ -5,7 +5,7 @@ import (
 
 	"encoding/json"
 
-	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -19,8 +19,7 @@ func TestMockKey_MonaxKeyJSON(t *testing.T) {
 	err = json.Unmarshal([]byte(monaxKey), keyJSON)
 	require.NoError(t, err)
 	// byte length of UUID string = 16 * 2 + 4 = 36
-	assert.Len(t, keyJSON.Id, 36)
 	assert.Equal(t, key.Address.String(), keyJSON.Address)
-	assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey)
-	assert.Equal(t, string(keys.KeyTypeEd25519Ripemd160), keyJSON.Type)
+	assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey.Plain)
+	assert.Equal(t, string(crypto.CurveTypeEd25519.String()), keyJSON.Type)
 }
diff --git a/keys/pbkeys/keys.pb.go b/keys/pbkeys/keys.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..a099818d370ebfe3db85f66d429ccafa7ed8a008
--- /dev/null
+++ b/keys/pbkeys/keys.pb.go
@@ -0,0 +1,977 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: keys.proto
+
+/*
+Package pbkeys is a generated protocol buffer package.
+
+It is generated from these files:
+	keys.proto
+
+It has these top-level messages:
+	Name
+	Empty
+	GenRequest
+	GenResponse
+	PubRequest
+	PubResponse
+	ImportJSONRequest
+	ImportResponse
+	ImportRequest
+	ExportRequest
+	ExportResponse
+	SignRequest
+	SignResponse
+	VerifyRequest
+	HashRequest
+	HashResponse
+	Key
+	ListResponse
+	AddNameRequest
+*/
+package pbkeys
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+	context "golang.org/x/net/context"
+	grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Name struct {
+	Keyname string `protobuf:"bytes,1,opt,name=keyname" json:"keyname,omitempty"`
+}
+
+func (m *Name) Reset()                    { *m = Name{} }
+func (m *Name) String() string            { return proto.CompactTextString(m) }
+func (*Name) ProtoMessage()               {}
+func (*Name) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Name) GetKeyname() string {
+	if m != nil {
+		return m.Keyname
+	}
+	return ""
+}
+
+type Empty struct {
+}
+
+func (m *Empty) Reset()                    { *m = Empty{} }
+func (m *Empty) String() string            { return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage()               {}
+func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+type GenRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
+	Curvetype  string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"`
+	Keyname    string `protobuf:"bytes,3,opt,name=keyname" json:"keyname,omitempty"`
+}
+
+func (m *GenRequest) Reset()                    { *m = GenRequest{} }
+func (m *GenRequest) String() string            { return proto.CompactTextString(m) }
+func (*GenRequest) ProtoMessage()               {}
+func (*GenRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *GenRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *GenRequest) GetCurvetype() string {
+	if m != nil {
+		return m.Curvetype
+	}
+	return ""
+}
+
+func (m *GenRequest) GetKeyname() string {
+	if m != nil {
+		return m.Keyname
+	}
+	return ""
+}
+
+type GenResponse struct {
+	Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *GenResponse) Reset()                    { *m = GenResponse{} }
+func (m *GenResponse) String() string            { return proto.CompactTextString(m) }
+func (*GenResponse) ProtoMessage()               {}
+func (*GenResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+
+func (m *GenResponse) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+type PubRequest struct {
+	Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+}
+
+func (m *PubRequest) Reset()                    { *m = PubRequest{} }
+func (m *PubRequest) String() string            { return proto.CompactTextString(m) }
+func (*PubRequest) ProtoMessage()               {}
+func (*PubRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+
+func (m *PubRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *PubRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+type PubResponse struct {
+	Pub       []byte `protobuf:"bytes,1,opt,name=pub,proto3" json:"pub,omitempty"`
+	Curvetype string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"`
+}
+
+func (m *PubResponse) Reset()                    { *m = PubResponse{} }
+func (m *PubResponse) String() string            { return proto.CompactTextString(m) }
+func (*PubResponse) ProtoMessage()               {}
+func (*PubResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
+
+func (m *PubResponse) GetPub() []byte {
+	if m != nil {
+		return m.Pub
+	}
+	return nil
+}
+
+func (m *PubResponse) GetCurvetype() string {
+	if m != nil {
+		return m.Curvetype
+	}
+	return ""
+}
+
+type ImportJSONRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
+	JSON       string `protobuf:"bytes,2,opt,name=JSON" json:"JSON,omitempty"`
+}
+
+func (m *ImportJSONRequest) Reset()                    { *m = ImportJSONRequest{} }
+func (m *ImportJSONRequest) String() string            { return proto.CompactTextString(m) }
+func (*ImportJSONRequest) ProtoMessage()               {}
+func (*ImportJSONRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
+
+func (m *ImportJSONRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ImportJSONRequest) GetJSON() string {
+	if m != nil {
+		return m.JSON
+	}
+	return ""
+}
+
+type ImportResponse struct {
+	Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *ImportResponse) Reset()                    { *m = ImportResponse{} }
+func (m *ImportResponse) String() string            { return proto.CompactTextString(m) }
+func (*ImportResponse) ProtoMessage()               {}
+func (*ImportResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
+
+func (m *ImportResponse) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+type ImportRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
+	Name       string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+	Curvetype  string `protobuf:"bytes,3,opt,name=curvetype" json:"curvetype,omitempty"`
+	Keybytes   []byte `protobuf:"bytes,4,opt,name=keybytes,proto3" json:"keybytes,omitempty"`
+}
+
+func (m *ImportRequest) Reset()                    { *m = ImportRequest{} }
+func (m *ImportRequest) String() string            { return proto.CompactTextString(m) }
+func (*ImportRequest) ProtoMessage()               {}
+func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+
+func (m *ImportRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetCurvetype() string {
+	if m != nil {
+		return m.Curvetype
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetKeybytes() []byte {
+	if m != nil {
+		return m.Keybytes
+	}
+	return nil
+}
+
+type ExportRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
+	Name       string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+	Address    string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *ExportRequest) Reset()                    { *m = ExportRequest{} }
+func (m *ExportRequest) String() string            { return proto.CompactTextString(m) }
+func (*ExportRequest) ProtoMessage()               {}
+func (*ExportRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
+
+func (m *ExportRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ExportRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *ExportRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+type ExportResponse struct {
+	Export string `protobuf:"bytes,1,opt,name=export" json:"export,omitempty"`
+}
+
+func (m *ExportResponse) Reset()                    { *m = ExportResponse{} }
+func (m *ExportResponse) String() string            { return proto.CompactTextString(m) }
+func (*ExportResponse) ProtoMessage()               {}
+func (*ExportResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
+
+func (m *ExportResponse) GetExport() string {
+	if m != nil {
+		return m.Export
+	}
+	return ""
+}
+
+type SignRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
+	Address    string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
+	Name       string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"`
+	Message    []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (m *SignRequest) Reset()                    { *m = SignRequest{} }
+func (m *SignRequest) String() string            { return proto.CompactTextString(m) }
+func (*SignRequest) ProtoMessage()               {}
+func (*SignRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
+
+func (m *SignRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *SignRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *SignRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *SignRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+type SignResponse struct {
+	Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
+	Curvetype string `protobuf:"bytes,2,opt,name=curvetype" json:"curvetype,omitempty"`
+}
+
+func (m *SignResponse) Reset()                    { *m = SignResponse{} }
+func (m *SignResponse) String() string            { return proto.CompactTextString(m) }
+func (*SignResponse) ProtoMessage()               {}
+func (*SignResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
+
+func (m *SignResponse) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+func (m *SignResponse) GetCurvetype() string {
+	if m != nil {
+		return m.Curvetype
+	}
+	return ""
+}
+
+type VerifyRequest struct {
+	Curvetype string `protobuf:"bytes,1,opt,name=curvetype" json:"curvetype,omitempty"`
+	Pub       []byte `protobuf:"bytes,2,opt,name=pub,proto3" json:"pub,omitempty"`
+	Message   []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
+}
+
+func (m *VerifyRequest) Reset()                    { *m = VerifyRequest{} }
+func (m *VerifyRequest) String() string            { return proto.CompactTextString(m) }
+func (*VerifyRequest) ProtoMessage()               {}
+func (*VerifyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
+
+func (m *VerifyRequest) GetCurvetype() string {
+	if m != nil {
+		return m.Curvetype
+	}
+	return ""
+}
+
+func (m *VerifyRequest) GetPub() []byte {
+	if m != nil {
+		return m.Pub
+	}
+	return nil
+}
+
+func (m *VerifyRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (m *VerifyRequest) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+type HashRequest struct {
+	Hashtype string `protobuf:"bytes,1,opt,name=hashtype" json:"hashtype,omitempty"`
+	Message  []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (m *HashRequest) Reset()                    { *m = HashRequest{} }
+func (m *HashRequest) String() string            { return proto.CompactTextString(m) }
+func (*HashRequest) ProtoMessage()               {}
+func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
+
+func (m *HashRequest) GetHashtype() string {
+	if m != nil {
+		return m.Hashtype
+	}
+	return ""
+}
+
+func (m *HashRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+type HashResponse struct {
+	Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"`
+}
+
+func (m *HashResponse) Reset()                    { *m = HashResponse{} }
+func (m *HashResponse) String() string            { return proto.CompactTextString(m) }
+func (*HashResponse) ProtoMessage()               {}
+func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
+
+func (m *HashResponse) GetHash() string {
+	if m != nil {
+		return m.Hash
+	}
+	return ""
+}
+
+type Key struct {
+	Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+	Keyname string `protobuf:"bytes,2,opt,name=keyname" json:"keyname,omitempty"`
+}
+
+func (m *Key) Reset()                    { *m = Key{} }
+func (m *Key) String() string            { return proto.CompactTextString(m) }
+func (*Key) ProtoMessage()               {}
+func (*Key) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
+
+func (m *Key) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *Key) GetKeyname() string {
+	if m != nil {
+		return m.Keyname
+	}
+	return ""
+}
+
+type ListResponse struct {
+	Key []*Key `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
+}
+
+func (m *ListResponse) Reset()                    { *m = ListResponse{} }
+func (m *ListResponse) String() string            { return proto.CompactTextString(m) }
+func (*ListResponse) ProtoMessage()               {}
+func (*ListResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
+
+func (m *ListResponse) GetKey() []*Key {
+	if m != nil {
+		return m.Key
+	}
+	return nil
+}
+
+type AddNameRequest struct {
+	Keyname string `protobuf:"bytes,1,opt,name=keyname" json:"keyname,omitempty"`
+	Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *AddNameRequest) Reset()                    { *m = AddNameRequest{} }
+func (m *AddNameRequest) String() string            { return proto.CompactTextString(m) }
+func (*AddNameRequest) ProtoMessage()               {}
+func (*AddNameRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
+
+func (m *AddNameRequest) GetKeyname() string {
+	if m != nil {
+		return m.Keyname
+	}
+	return ""
+}
+
+func (m *AddNameRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func init() {
+	proto.RegisterType((*Name)(nil), "pbkeys.Name")
+	proto.RegisterType((*Empty)(nil), "pbkeys.Empty")
+	proto.RegisterType((*GenRequest)(nil), "pbkeys.GenRequest")
+	proto.RegisterType((*GenResponse)(nil), "pbkeys.GenResponse")
+	proto.RegisterType((*PubRequest)(nil), "pbkeys.PubRequest")
+	proto.RegisterType((*PubResponse)(nil), "pbkeys.PubResponse")
+	proto.RegisterType((*ImportJSONRequest)(nil), "pbkeys.ImportJSONRequest")
+	proto.RegisterType((*ImportResponse)(nil), "pbkeys.ImportResponse")
+	proto.RegisterType((*ImportRequest)(nil), "pbkeys.ImportRequest")
+	proto.RegisterType((*ExportRequest)(nil), "pbkeys.ExportRequest")
+	proto.RegisterType((*ExportResponse)(nil), "pbkeys.ExportResponse")
+	proto.RegisterType((*SignRequest)(nil), "pbkeys.SignRequest")
+	proto.RegisterType((*SignResponse)(nil), "pbkeys.SignResponse")
+	proto.RegisterType((*VerifyRequest)(nil), "pbkeys.VerifyRequest")
+	proto.RegisterType((*HashRequest)(nil), "pbkeys.HashRequest")
+	proto.RegisterType((*HashResponse)(nil), "pbkeys.HashResponse")
+	proto.RegisterType((*Key)(nil), "pbkeys.Key")
+	proto.RegisterType((*ListResponse)(nil), "pbkeys.ListResponse")
+	proto.RegisterType((*AddNameRequest)(nil), "pbkeys.AddNameRequest")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for Keys service
+
+type KeysClient interface {
+	GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error)
+	PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error)
+	Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
+	Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*Empty, error)
+	Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error)
+	ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error)
+	Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error)
+	Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error)
+	RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error)
+	List(ctx context.Context, in *Name, opts ...grpc.CallOption) (*ListResponse, error)
+	AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error)
+}
+
+type keysClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewKeysClient(cc *grpc.ClientConn) KeysClient {
+	return &keysClient{cc}
+}
+
+func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) {
+	out := new(GenResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/GenerateKey", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) {
+	out := new(PubResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/PublicKey", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) {
+	out := new(SignResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/Sign", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/Verify", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
+	out := new(ImportResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/Import", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
+	out := new(ImportResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/ImportJSON", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) {
+	out := new(ExportResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/Export", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) {
+	out := new(HashResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/Hash", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/RemoveName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) List(ctx context.Context, in *Name, opts ...grpc.CallOption) (*ListResponse, error) {
+	out := new(ListResponse)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/List", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := grpc.Invoke(ctx, "/pbkeys.Keys/AddName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Server API for Keys service
+
+type KeysServer interface {
+	GenerateKey(context.Context, *GenRequest) (*GenResponse, error)
+	PublicKey(context.Context, *PubRequest) (*PubResponse, error)
+	Sign(context.Context, *SignRequest) (*SignResponse, error)
+	Verify(context.Context, *VerifyRequest) (*Empty, error)
+	Import(context.Context, *ImportRequest) (*ImportResponse, error)
+	ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error)
+	Export(context.Context, *ExportRequest) (*ExportResponse, error)
+	Hash(context.Context, *HashRequest) (*HashResponse, error)
+	RemoveName(context.Context, *Name) (*Empty, error)
+	List(context.Context, *Name) (*ListResponse, error)
+	AddName(context.Context, *AddNameRequest) (*Empty, error)
+}
+
+func RegisterKeysServer(s *grpc.Server, srv KeysServer) {
+	s.RegisterService(&_Keys_serviceDesc, srv)
+}
+
+func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GenRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).GenerateKey(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/GenerateKey",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(PubRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).PublicKey(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/PublicKey",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SignRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Sign(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/Sign",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Sign(ctx, req.(*SignRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(VerifyRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Verify(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/Verify",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ImportRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Import(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/Import",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Import(ctx, req.(*ImportRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ImportJSONRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).ImportJSON(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/ImportJSON",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ExportRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Export(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/Export",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Export(ctx, req.(*ExportRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(HashRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Hash(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/Hash",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Hash(ctx, req.(*HashRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Name)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).RemoveName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/RemoveName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).RemoveName(ctx, req.(*Name))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Name)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).List(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/List",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).List(ctx, req.(*Name))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AddNameRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).AddName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pbkeys.Keys/AddName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Keys_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "pbkeys.Keys",
+	HandlerType: (*KeysServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GenerateKey",
+			Handler:    _Keys_GenerateKey_Handler,
+		},
+		{
+			MethodName: "PublicKey",
+			Handler:    _Keys_PublicKey_Handler,
+		},
+		{
+			MethodName: "Sign",
+			Handler:    _Keys_Sign_Handler,
+		},
+		{
+			MethodName: "Verify",
+			Handler:    _Keys_Verify_Handler,
+		},
+		{
+			MethodName: "Import",
+			Handler:    _Keys_Import_Handler,
+		},
+		{
+			MethodName: "ImportJSON",
+			Handler:    _Keys_ImportJSON_Handler,
+		},
+		{
+			MethodName: "Export",
+			Handler:    _Keys_Export_Handler,
+		},
+		{
+			MethodName: "Hash",
+			Handler:    _Keys_Hash_Handler,
+		},
+		{
+			MethodName: "RemoveName",
+			Handler:    _Keys_RemoveName_Handler,
+		},
+		{
+			MethodName: "List",
+			Handler:    _Keys_List_Handler,
+		},
+		{
+			MethodName: "AddName",
+			Handler:    _Keys_AddName_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "keys.proto",
+}
+
+func init() { proto.RegisterFile("keys.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 640 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x51, 0x6f, 0xd3, 0x3c,
+	0x14, 0x55, 0x9b, 0x7c, 0xdd, 0x7a, 0xda, 0x4e, 0x1f, 0x06, 0xa6, 0x52, 0x0d, 0x34, 0xf9, 0x85,
+	0x31, 0x89, 0x8a, 0x0d, 0xc4, 0x04, 0x12, 0x42, 0x08, 0xa6, 0xc1, 0x86, 0xc6, 0xd4, 0x49, 0xbc,
+	0xf1, 0x90, 0xae, 0x97, 0xb5, 0x2a, 0x69, 0x43, 0x9c, 0x0c, 0xf2, 0xc0, 0xdf, 0xe3, 0x77, 0x21,
+	0x3b, 0x76, 0x6d, 0x47, 0xeb, 0xa8, 0xc4, 0x9b, 0xef, 0xcd, 0xbd, 0xf7, 0x1c, 0xdf, 0x9c, 0x9c,
+	0x00, 0x53, 0x2a, 0x44, 0x3f, 0x49, 0xe7, 0xd9, 0x9c, 0x35, 0x92, 0xa1, 0x8c, 0xf8, 0x36, 0xc2,
+	0xd3, 0x28, 0x26, 0xd6, 0xc5, 0xda, 0x94, 0x8a, 0x59, 0x14, 0x53, 0xb7, 0xb6, 0x5d, 0xdb, 0x69,
+	0x0e, 0x4c, 0xc8, 0xd7, 0xf0, 0xdf, 0x61, 0x9c, 0x64, 0x05, 0x1f, 0x01, 0x47, 0x34, 0x1b, 0xd0,
+	0xf7, 0x9c, 0x44, 0xc6, 0x1e, 0x00, 0x49, 0x24, 0x44, 0x32, 0x4e, 0x23, 0x61, 0x7a, 0x9c, 0x0c,
+	0xdb, 0x42, 0xf3, 0x22, 0x4f, 0xaf, 0x28, 0x2b, 0x12, 0xea, 0xd6, 0xd5, 0x63, 0x9b, 0x70, 0xe1,
+	0x02, 0x1f, 0xee, 0x21, 0x5a, 0x0a, 0x45, 0x24, 0xf3, 0x99, 0x50, 0x85, 0xd1, 0x68, 0x94, 0x92,
+	0x10, 0x86, 0x97, 0x0e, 0xf9, 0x4b, 0xe0, 0x2c, 0x1f, 0x1a, 0x3a, 0x4b, 0xeb, 0x18, 0x43, 0xa8,
+	0x70, 0x4a, 0x0e, 0xea, 0xcc, 0x5f, 0xa1, 0xa5, 0x7a, 0x35, 0xc8, 0xff, 0x08, 0x92, 0x7c, 0xa8,
+	0x1a, 0xdb, 0x03, 0x79, 0xbc, 0x99, 0x3d, 0x3f, 0xc2, 0xad, 0x0f, 0x71, 0x32, 0x4f, 0xb3, 0xe3,
+	0xf3, 0x4f, 0xa7, 0xab, 0x2e, 0x84, 0x21, 0x94, 0xe5, 0x86, 0x87, 0x3c, 0xf3, 0x5d, 0x6c, 0x94,
+	0x83, 0x56, 0xb8, 0xef, 0x2f, 0x74, 0x4c, 0xed, 0xca, 0x80, 0xd5, 0x8b, 0xfb, 0xf7, 0x0a, 0xaa,
+	0x6f, 0xa5, 0x87, 0xf5, 0x29, 0x15, 0xc3, 0x22, 0x23, 0xd1, 0x0d, 0xd5, 0x32, 0x16, 0x31, 0xff,
+	0x82, 0xce, 0xe1, 0xcf, 0x7f, 0x85, 0x77, 0x6e, 0x17, 0xf8, 0xb7, 0xdb, 0xc1, 0x86, 0x19, 0xaf,
+	0x37, 0xb1, 0x89, 0x06, 0xa9, 0x8c, 0x9e, 0xad, 0x23, 0x9e, 0xa3, 0x75, 0x3e, 0xb9, 0x5c, 0x59,
+	0x87, 0x0e, 0x64, 0xfd, 0x7a, 0x61, 0x04, 0x3e, 0xc1, 0x98, 0x84, 0x88, 0x2e, 0x49, 0x2f, 0xc0,
+	0x84, 0xfc, 0x18, 0xed, 0x12, 0x56, 0xd3, 0xdb, 0x42, 0x53, 0x4c, 0x2e, 0x67, 0x51, 0x96, 0xa7,
+	0xa4, 0x95, 0x63, 0x13, 0x7f, 0xd1, 0xcf, 0x0f, 0x74, 0x3e, 0x53, 0x3a, 0xf9, 0x5a, 0x98, 0x4b,
+	0x78, 0xe5, 0xb5, 0xea, 0x6b, 0xd1, 0xf2, 0xac, 0x5b, 0x79, 0x3a, 0x34, 0x03, 0x8f, 0xa6, 0x4f,
+	0x2b, 0xac, 0xd0, 0xe2, 0x6f, 0xd1, 0x7a, 0x1f, 0x89, 0xb1, 0x81, 0xed, 0x61, 0x7d, 0x1c, 0x89,
+	0xb1, 0x83, 0xba, 0x88, 0x5d, 0x88, 0xba, 0xbf, 0x09, 0x8e, 0x76, 0x39, 0x44, 0x6f, 0x82, 0x21,
+	0x94, 0x5d, 0x7a, 0x82, 0x3a, 0xf3, 0x17, 0x08, 0x4e, 0xa8, 0xb8, 0xe1, 0xab, 0x74, 0x0c, 0xa0,
+	0xee, 0x1b, 0xc0, 0x63, 0xb4, 0x3f, 0x4e, 0x84, 0xd5, 0xc1, 0x7d, 0x04, 0x53, 0x2a, 0xba, 0xb5,
+	0xed, 0x60, 0xa7, 0xb5, 0xdf, 0xea, 0x97, 0xbe, 0xd5, 0x3f, 0xa1, 0x62, 0x20, 0xf3, 0xfc, 0x1d,
+	0x36, 0xde, 0x8c, 0x46, 0xd2, 0xc3, 0x1c, 0x2b, 0xb8, 0xde, 0xca, 0x96, 0x6b, 0x61, 0xff, 0x77,
+	0x88, 0xf0, 0x84, 0x0a, 0xc1, 0x9e, 0x2b, 0xfb, 0xa1, 0x34, 0xca, 0x48, 0x5e, 0x80, 0x19, 0x3c,
+	0xeb, 0x7c, 0xbd, 0xdb, 0x5e, 0x4e, 0xb3, 0x7c, 0x86, 0xe6, 0x59, 0x3e, 0xfc, 0x36, 0xb9, 0xf0,
+	0xba, 0xac, 0x41, 0xd9, 0x2e, 0xd7, 0x78, 0xf6, 0x10, 0x4a, 0x51, 0xb1, 0xc5, 0x43, 0x47, 0xd9,
+	0xbd, 0x3b, 0x7e, 0x52, 0xb7, 0xf4, 0xd1, 0x28, 0xb5, 0xc3, 0xee, 0x9a, 0xe7, 0x9e, 0x96, 0x7a,
+	0x1d, 0x93, 0x56, 0xae, 0xcd, 0x0e, 0xd0, 0x28, 0x6d, 0xc3, 0xd6, 0x7b, 0x36, 0xd2, 0xdb, 0xac,
+	0xa6, 0x35, 0xd0, 0x6b, 0xc0, 0x9a, 0x1c, 0xbb, 0xe7, 0x57, 0x39, 0xc6, 0xb7, 0x74, 0xc0, 0x01,
+	0x1a, 0xe5, 0x27, 0x6d, 0x91, 0x3d, 0x07, 0xb1, 0x8d, 0x95, 0x2f, 0x7f, 0x0f, 0xa1, 0x14, 0x98,
+	0xdd, 0x8a, 0xa3, 0x59, 0xbb, 0x15, 0x4f, 0x83, 0x8f, 0x80, 0x01, 0xc5, 0xf3, 0x2b, 0x52, 0x3f,
+	0xb3, 0xb6, 0xa9, 0x91, 0x51, 0x75, 0x21, 0xbb, 0x08, 0xa5, 0xbe, 0x2a, 0x45, 0x8b, 0xb1, 0x9e,
+	0xf6, 0x9e, 0x60, 0x4d, 0x8b, 0x8b, 0x2d, 0xc8, 0xfa, 0x6a, 0xab, 0x4c, 0x1f, 0x36, 0xd4, 0xef,
+	0xf5, 0xe9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xed, 0x32, 0x21, 0x6c, 0x07, 0x00, 0x00,
+}
diff --git a/keys/pbkeys/keys.proto b/keys/pbkeys/keys.proto
new file mode 100644
index 0000000000000000000000000000000000000000..06ef091eee5694daa1f546e04a85badf2acb9f9e
--- /dev/null
+++ b/keys/pbkeys/keys.proto
@@ -0,0 +1,113 @@
+syntax = "proto3";
+
+package pbkeys;
+
+service Keys {
+    rpc GenerateKey(GenRequest) returns (GenResponse);
+    rpc PublicKey(PubRequest) returns (PubResponse);
+    rpc Sign(SignRequest) returns (SignResponse);
+    rpc Verify(VerifyRequest) returns (Empty);
+    rpc Import(ImportRequest) returns (ImportResponse);
+    rpc ImportJSON(ImportJSONRequest) returns (ImportResponse);
+    rpc Export(ExportRequest) returns (ExportResponse);
+    rpc Hash(HashRequest) returns (HashResponse);
+    rpc RemoveName(Name) returns (Empty);
+    rpc List(Name) returns (ListResponse);
+    rpc AddName(AddNameRequest) returns (Empty);
+}
+
+message Name {
+    string keyname = 1;
+}
+
+message Empty {
+
+}
+
+message GenRequest {
+    string passphrase = 1;
+    string curvetype = 2;
+    string keyname = 3;
+}
+
+message GenResponse {
+    string address = 1;
+}
+
+message PubRequest {
+    string address = 1;
+    string name = 2;
+} 
+
+message PubResponse {
+    bytes pub = 1;
+    string curvetype = 2;
+}
+
+message ImportJSONRequest {
+    string passphrase = 1;
+    string JSON = 2;
+}
+
+message ImportResponse {
+    string address = 1;
+}
+
+message ImportRequest {
+    string passphrase = 1;
+    string name = 2;
+    string curvetype = 3;
+    bytes keybytes = 4;
+}
+
+message ExportRequest {
+    string passphrase = 1;
+    string name = 2;
+    string address = 3;
+}
+
+message ExportResponse {
+    string export = 1;
+}
+
+message SignRequest {
+    string passphrase = 1;
+    string address = 2;
+    string name = 3;
+    bytes message = 4;
+}
+
+message SignResponse {
+    bytes signature = 1;
+    string curvetype = 2;
+}
+
+message VerifyRequest {
+    string curvetype = 1;
+    bytes pub = 2;
+    bytes message = 3;
+    bytes signature = 4;
+}
+
+message HashRequest {
+    string hashtype = 1;
+    bytes message = 2;
+}
+
+message HashResponse {
+    string hash = 1;
+}
+
+message Key {
+    string address = 1;
+    string keyname = 2;
+}
+
+message ListResponse {
+    repeated Key key = 1;
+}
+
+message AddNameRequest {
+    string keyname = 1;
+    string address = 2;
+}
diff --git a/keys/server.go b/keys/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ffa0e4375084c987baf075fea31fdc00dc5e8f5
--- /dev/null
+++ b/keys/server.go
@@ -0,0 +1,245 @@
+package keys
+
+import (
+	"context"
+	"crypto/sha256"
+	"fmt"
+	"hash"
+	"net"
+	"strings"
+
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/keys/pbkeys"
+	"github.com/tmthrgd/go-hex"
+	"golang.org/x/crypto/ripemd160"
+	"google.golang.org/grpc"
+)
+
+//------------------------------------------------------------------------
+// all cli commands pass through the http KeyStore
+// the KeyStore process also maintains the unlocked accounts
+
+func StartStandAloneServer(keysDir, host, port string) error {
+	listen, err := net.Listen("tcp", host+":"+port)
+	if err != nil {
+		return err
+	}
+
+	ks := NewKeyStore(keysDir)
+
+	grpcServer := grpc.NewServer()
+	pbkeys.RegisterKeysServer(grpcServer, &ks)
+	return grpcServer.Serve(listen)
+}
+
+//------------------------------------------------------------------------
+// handlers
+
+func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) {
+	curveT, err := crypto.CurveTypeFromString(in.Curvetype)
+	if err != nil {
+		return nil, err
+	}
+
+	key, err := k.Gen(in.Passphrase, curveT)
+	if err != nil {
+		return nil, fmt.Errorf("error generating key %s %s", curveT, err)
+	}
+
+	addrH := key.Address.String()
+	if in.Keyname != "" {
+		err = coreNameAdd(k.keysDirPath, in.Keyname, addrH)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return &pbkeys.GenResponse{Address: addrH}, nil
+}
+
+func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) {
+	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
+
+	if err != nil {
+		return nil, err
+	}
+
+	addrB, err := crypto.AddressFromHexString(addr)
+	if err != nil {
+		return nil, err
+	}
+
+	// No phrase needed for public key. I hope.
+	key, err := k.GetKey(in.GetPassphrase(), addrB.Bytes())
+	if err != nil {
+		return nil, err
+	}
+	resp, err := coreExport(key)
+	if err != nil {
+		return nil, err
+	}
+
+	return &pbkeys.ExportResponse{Export: string(resp)}, nil
+}
+
+func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) {
+	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
+	if err != nil {
+		return nil, err
+	}
+
+	addrB, err := crypto.AddressFromHexString(addr)
+	if err != nil {
+		return nil, err
+	}
+
+	// No phrase needed for public key. I hope.
+	key, err := k.GetKey("", addrB.Bytes())
+	if key == nil {
+		return nil, err
+	}
+
+	return &pbkeys.PubResponse{Curvetype: key.CurveType.String(), Pub: key.Pubkey()}, nil
+}
+
+func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) {
+	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
+	if err != nil {
+		return nil, err
+	}
+
+	addrB, err := crypto.AddressFromHexString(addr)
+	if err != nil {
+		return nil, err
+	}
+
+	key, err := k.GetKey(in.GetPassphrase(), addrB[:])
+	if err != nil {
+		return nil, err
+	}
+
+	sig, err := key.Sign(in.GetMessage())
+
+	return &pbkeys.SignResponse{Signature: sig}, nil
+}
+
+func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.Empty, error) {
+	if in.GetPub() == nil {
+		return nil, fmt.Errorf("must provide a pubkey")
+	}
+	if in.GetMessage() == nil {
+		return nil, fmt.Errorf("must provide a message")
+	}
+	if in.GetSignature() == nil {
+		return nil, fmt.Errorf("must provide a signature")
+	}
+
+	curveT, err := crypto.CurveTypeFromString(in.GetCurvetype())
+	if err != nil {
+		return nil, err
+	}
+	sig, err := crypto.SignatureFromBytes(in.GetSignature(), curveT)
+	if err != nil {
+		return nil, err
+	}
+	pubkey, err := crypto.PublicKeyFromBytes(in.GetPub(), curveT)
+	if err != nil {
+		return nil, err
+	}
+	match := pubkey.Verify(in.GetMessage(), sig)
+	if !match {
+		return nil, fmt.Errorf("Signature does not match")
+	}
+
+	return &pbkeys.Empty{}, nil
+}
+
+func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) {
+	var hasher hash.Hash
+	switch in.GetHashtype() {
+	case "ripemd160":
+		hasher = ripemd160.New()
+	case "sha256":
+		hasher = sha256.New()
+	// case "sha3":
+	default:
+		return nil, fmt.Errorf("Unknown hash type %v", in.GetHashtype())
+	}
+
+	hasher.Write(in.GetMessage())
+
+	return &pbkeys.HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil
+}
+
+func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) {
+	keyJSON := []byte(in.GetJSON())
+	var err error
+	addr := IsValidKeyJson(keyJSON)
+	if addr != nil {
+		_, err = writeKey(k.keysDirPath, addr, keyJSON)
+	} else {
+		err = fmt.Errorf("invalid json key passed on command line")
+	}
+	if err != nil {
+		return nil, err
+	}
+	return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil
+}
+
+func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) {
+	curveT, err := crypto.CurveTypeFromString(in.GetCurvetype())
+	if err != nil {
+		return nil, err
+	}
+	key, err := NewKeyFromPriv(curveT, in.GetKeybytes())
+	if err != nil {
+		return nil, err
+	}
+
+	// store the new key
+	if err = k.StoreKey(in.GetPassphrase(), key); err != nil {
+		return nil, err
+	}
+
+	if in.GetName() != "" {
+		if err := coreNameAdd(k.keysDirPath, in.GetName(), key.Address.String()); err != nil {
+			return nil, err
+		}
+	}
+	return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil
+}
+
+func (k *KeyStore) List(ctx context.Context, in *pbkeys.Name) (*pbkeys.ListResponse, error) {
+	names, err := coreNameList(k.keysDirPath)
+	if err != nil {
+		return nil, err
+	}
+
+	var list []*pbkeys.Key
+
+	for name, addr := range names {
+		list = append(list, &pbkeys.Key{Keyname: name, Address: addr})
+	}
+
+	return &pbkeys.ListResponse{Key: list}, nil
+}
+
+func (k *KeyStore) RemoveName(ctx context.Context, in *pbkeys.Name) (*pbkeys.Empty, error) {
+	if in.GetKeyname() == "" {
+		return nil, fmt.Errorf("please specify a name")
+	}
+
+	return &pbkeys.Empty{}, coreNameRm(k.keysDirPath, in.GetKeyname())
+}
+
+func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbkeys.Empty, error) {
+	if in.GetKeyname() == "" {
+		return nil, fmt.Errorf("please specify a name")
+	}
+
+	if in.GetAddress() == "" {
+		return nil, fmt.Errorf("please specify an address")
+	}
+
+	return &pbkeys.Empty{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress()))
+}
diff --git a/keys/server_test.go b/keys/server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..614daaecb6f9eba0950acc29d9b1d43feef7f72a
--- /dev/null
+++ b/keys/server_test.go
@@ -0,0 +1,179 @@
+package keys
+
+import (
+	"bytes"
+	"context"
+	"crypto/sha256"
+	"fmt"
+	"os"
+	"testing"
+	"time"
+
+	"golang.org/x/crypto/ripemd160"
+
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/execution/evm/sha3"
+	"github.com/hyperledger/burrow/keys/pbkeys"
+	tm_crypto "github.com/tendermint/go-crypto"
+	"google.golang.org/grpc"
+)
+
+type hashInfo struct {
+	data     string
+	expected string
+}
+
+var hashData = map[string]hashInfo{
+	"sha256":    {"hi", "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4"},
+	"ripemd160": {"hi", "242485AB6BFD3502BCB3442EA2E211687B8E4D89"},
+}
+
+var (
+	KEY_TYPES  = []string{"ed25519", "secp256k1"}
+	HASH_TYPES = []string{"sha256", "ripemd160"}
+)
+
+// start the server
+func init() {
+	failedCh := make(chan error)
+	go func() {
+		err := StartStandAloneServer(DefaultKeysDir, DefaultHost, TestPort)
+		failedCh <- err
+	}()
+	tick := time.NewTicker(time.Second)
+	select {
+	case err := <-failedCh:
+		fmt.Println(err)
+		os.Exit(1)
+	case <-tick.C:
+	}
+}
+
+func grpcKeysClient() pbkeys.KeysClient {
+	var opts []grpc.DialOption
+	opts = append(opts, grpc.WithInsecure())
+	conn, err := grpc.Dial(DefaultHost+":"+TestPort, opts...)
+	if err != nil {
+		fmt.Printf("Failed to connect to grpc server: %v\n", err)
+		os.Exit(1)
+	}
+	return pbkeys.NewKeysClient(conn)
+}
+
+func checkAddrFromPub(typ string, pub, addr []byte) error {
+	var addr2 []byte
+	switch typ {
+	case "ed25519":
+		tmPubKey := new(tm_crypto.PubKeyEd25519)
+		copy(tmPubKey[:], pub)
+		addr2 = tmPubKey.Address()
+	case "secp256k1":
+		sha := sha256.New()
+		sha.Write(pub)
+
+		hash := ripemd160.New()
+		hash.Write(sha.Sum(nil))
+		addr2 = hash.Sum(nil)
+	default:
+		return fmt.Errorf("Unknown or incomplete typ %s", typ)
+	}
+	if bytes.Compare(addr, addr2) != 0 {
+		return fmt.Errorf("Keygen addr doesn't match pub. Got %X, expected %X", addr2, addr)
+	}
+	return nil
+}
+
+func testServerKeygenAndPub(t *testing.T, typ string) {
+	c := grpcKeysClient()
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ})
+	if err != nil {
+		t.Fatal(err)
+	}
+	addr := genresp.Address
+	resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr})
+	if err != nil {
+		t.Fatal(err)
+	}
+	addrB, err := crypto.AddressFromHexString(addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = checkAddrFromPub(typ, resp.GetPub(), addrB[:]); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestServerKeygenAndPub(t *testing.T) {
+	for _, typ := range KEY_TYPES {
+		testServerKeygenAndPub(t, typ)
+	}
+}
+
+func testServerSignAndVerify(t *testing.T, typ string) {
+	c := grpcKeysClient()
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ})
+	if err != nil {
+		t.Fatal(err)
+	}
+	addr := genresp.Address
+	resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr})
+	if err != nil {
+		t.Fatal(err)
+	}
+	hash := sha3.Sha3([]byte("the hash of something!"))
+
+	sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Message: hash})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	_, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Message: hash, Curvetype: typ})
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestServerSignAndVerify(t *testing.T) {
+	for _, typ := range KEY_TYPES {
+		testServerSignAndVerify(t, typ)
+	}
+}
+
+func testServerHash(t *testing.T, typ string) {
+	hData := hashData[typ]
+	data, expected := hData.data, hData.expected
+
+	c := grpcKeysClient()
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: typ, Message: []byte(data)})
+	if err != nil {
+		t.Fatal(err)
+	}
+	hash := resp.GetHash()
+
+	if hash != expected {
+		t.Fatalf("Hash error for %s. Got %s, expected %s", typ, hash, expected)
+	}
+}
+
+func TestServerHash(t *testing.T) {
+	for _, typ := range HASH_TYPES {
+		testServerHash(t, typ)
+	}
+}
+
+//---------------------------------------------------------------------------------
+
+func checkErrs(t *testing.T, errS string, err error) {
+	if err != nil {
+		t.Fatal(err)
+	}
+	if errS != "" {
+		t.Fatal(errS)
+	}
+}
diff --git a/keys/test.sh b/keys/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7bb16ed18f12b9ee425fdc03a178aaa4d91fb7cb
--- /dev/null
+++ b/keys/test.sh
@@ -0,0 +1,155 @@
+#! /bin/bash
+
+# tests
+# run the suite with and without the daemon
+
+# TODO: run the suite with/without encryption!
+
+
+burrow_bin=${burrow_bin:-burrow}
+
+echo "-----------------------------"
+echo "starting the server"
+$burrow_bin keys server &
+keys_pid=$!
+sleep 1
+echo "-----------------------------"
+echo "testing the cli"
+
+# we test keys, hashes, names, and import
+# this file should be run with and without the daemon running
+
+echo "testing keys"
+
+CURVETYPES=("ed25519" "secp256k1")
+for CURVETYPE in ${CURVETYPES[*]}
+do
+	# test key gen, sign verify:
+	# for each step, ensure it works using --addr or --name
+	echo "... $CURVETYPE"
+
+	HASH=`$burrow_bin keys hash --type sha256 ok`
+	#echo "HASH: $HASH"
+	NAME=testkey1
+	ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --name $NAME --no-password`
+	#echo "my addr: $ADDR"
+	PUB1=`$burrow_bin keys pub --name $NAME`
+	PUB2=`$burrow_bin keys pub --addr $ADDR`
+	if [ "$PUB1" != "$PUB2" ]; then
+		echo "FAILED pub: got $PUB2, expected $PUB1"
+		kill $keys_pid
+		exit 1
+	fi
+	echo "...... passed pub"
+
+	SIG1=`$burrow_bin keys sign --name $NAME $HASH`
+	VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG1 $PUB1`
+	if [ $VERIFY1 != "true" ]; then
+		echo "FAILED verify: got $VERIFY1 expected true"
+		kill $keys_pid
+		exit 1
+	fi
+
+	SIG2=`$burrow_bin keys sign --addr $ADDR $HASH`
+	VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG2 $PUB1`
+	if [ $VERIFY1 != "true" ]; then
+		echo "FAILED verify: got $VERIFY1 expected true"
+		kill $keys_pid
+		exit 1
+	fi
+
+	echo "...... passed sig/verify"
+
+done
+
+echo "testing hashes"
+# test hashing (we need openssl)
+TOHASH=okeydokey
+HASHTYPES=(sha256 ripemd160)
+for HASHTYPE in ${HASHTYPES[*]}
+do
+	echo  "... $HASHTYPE"
+	HASH0=`echo -n $TOHASH | openssl dgst -$HASHTYPE | awk '{print toupper($2)}'`
+	HASH1=`$burrow_bin keys hash --type $HASHTYPE $TOHASH`
+	if [ "$HASH0" != "$HASH1" ]; then
+		echo "FAILED hash $HASHTYPE: got $HASH1 expected $HASH0"
+	fi
+	echo "...... passed"
+done
+
+echo "testing imports"
+
+# TODO: IMPORTS
+# for each key type, import a priv key, ensure it returns
+# the right address. do again with both plain and encrypted jsons
+
+for CURVETYPE in ${CURVETYPES[*]}
+do
+	echo "... $CURVETYPE"
+	# create a key, get its address and priv, backup the json, delete the key
+	ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --no-password`
+	DIR=.keys/data
+	FILE=$DIR/$ADDR.json
+	PRIV=`cat $FILE |  jq -r .PrivateKey.Plain`
+	HEXPRIV=`echo -n "$PRIV" | base64 -d | xxd -p -u -c 256`
+	cp $FILE ~/$ADDR
+	rm -rf $DIR
+
+	# import the key via priv
+	ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $HEXPRIV`
+	if [ "$ADDR" != "$ADDR2" ]; then
+		echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR"
+		kill $keys_pid
+		exit
+	fi
+	rm -rf $DIR
+
+	# import the key via json
+	JSON=`cat ~/$ADDR`
+	ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $JSON`
+	if [ "$ADDR" != "$ADDR2" ]; then
+		echo "FAILED import (json) $CURVETYPE: got $ADDR2 expected $ADDR"
+		kill $keys_pid
+		exit
+	fi
+	rm -rf $DIR
+
+	# import the key via path
+	ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE ~/$ADDR`
+	if [ "$ADDR" != "$ADDR2" ]; then
+		echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR"
+		kill $keys_pid
+		exit
+	fi
+	rm -rf $DIR
+
+	echo "...... passed raw hex and json"
+done
+
+
+echo "testing names"
+
+NAME=mykey
+ADDR=`$burrow_bin keys gen --name $NAME --no-password`
+ADDR2=`$burrow_bin keys list --name $NAME`
+if [ "$ADDR" != "$ADDR2" ]; then
+	echo "FAILED name: got $ADDR2 expected $ADDR"
+	kill $keys_pid
+	exit
+fi
+
+NAME2=mykey2
+$burrow_bin keys name $NAME2 $ADDR
+ADDR2=`$burrow_bin keys list --name $NAME2`
+if [ "$ADDR" != "$ADDR2" ]; then
+	echo "FAILED rename: got $ADDR2 expected $ADDR"
+	kill $keys_pid
+	exit
+fi
+
+echo "... passed"
+
+kill $keys_pid
+
+# TODO a little more on names...
+
diff --git a/permission/snatives/snatives.go b/permission/snatives/snatives.go
index 2323d83b641b49ec8065b578499a663efe74303e..40e560ea9087903b220e5eaec49a82a3721ce352 100644
--- a/permission/snatives/snatives.go
+++ b/permission/snatives/snatives.go
@@ -18,7 +18,7 @@ import (
 	"fmt"
 	"strings"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/permission/types"
 )
@@ -28,7 +28,7 @@ import (
 
 type PermArgs struct {
 	PermFlag   types.PermFlag
-	Address    *acm.Address    `json:",omitempty"`
+	Address    *crypto.Address `json:",omitempty"`
 	Permission *types.PermFlag `json:",omitempty"`
 	Role       *string         `json:",omitempty"`
 	Value      *bool           `json:",omitempty"`
@@ -73,7 +73,7 @@ func (pa PermArgs) EnsureValid() error {
 	return nil
 }
 
-func HasBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs {
+func HasBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs {
 	return PermArgs{
 		PermFlag:   permission.HasBase,
 		Address:    &address,
@@ -81,7 +81,7 @@ func HasBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs {
 	}
 }
 
-func SetBaseArgs(address acm.Address, permFlag types.PermFlag, value bool) PermArgs {
+func SetBaseArgs(address crypto.Address, permFlag types.PermFlag, value bool) PermArgs {
 	return PermArgs{
 		PermFlag:   permission.SetBase,
 		Address:    &address,
@@ -90,7 +90,7 @@ func SetBaseArgs(address acm.Address, permFlag types.PermFlag, value bool) PermA
 	}
 }
 
-func UnsetBaseArgs(address acm.Address, permFlag types.PermFlag) PermArgs {
+func UnsetBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs {
 	return PermArgs{
 		PermFlag:   permission.UnsetBase,
 		Address:    &address,
@@ -106,7 +106,7 @@ func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs {
 	}
 }
 
-func HasRoleArgs(address acm.Address, role string) PermArgs {
+func HasRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
 		PermFlag: permission.HasRole,
 		Address:  &address,
@@ -114,7 +114,7 @@ func HasRoleArgs(address acm.Address, role string) PermArgs {
 	}
 }
 
-func AddRoleArgs(address acm.Address, role string) PermArgs {
+func AddRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
 		PermFlag: permission.AddRole,
 		Address:  &address,
@@ -122,7 +122,7 @@ func AddRoleArgs(address acm.Address, role string) PermArgs {
 	}
 }
 
-func RemoveRoleArgs(address acm.Address, role string) PermArgs {
+func RemoveRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
 		PermFlag: permission.RemoveRole,
 		Address:  &address,
diff --git a/rpc/config.go b/rpc/config.go
index eba0b7ed93758a45b0ae21539031dee279f579f1..9449609d98ead8a4330fa4fac0f4d2a8930ff9bf 100644
--- a/rpc/config.go
+++ b/rpc/config.go
@@ -3,23 +3,29 @@ package rpc
 import "github.com/hyperledger/burrow/rpc/v0/server"
 
 type RPCConfig struct {
-	V0       *V0Config       `json:",omitempty" toml:",omitempty"`
-	TM       *TMConfig       `json:",omitempty" toml:",omitempty"`
-	Profiler *ProfilerConfig `json:",omitempty" toml:",omitempty"`
+	V0       *V0Config     `json:",omitempty" toml:",omitempty"`
+	TM       *ServerConfig `json:",omitempty" toml:",omitempty"`
+	Profiler *ServerConfig `json:",omitempty" toml:",omitempty"`
+	GRPC     *ServerConfig `json:",omitempty" toml:",omitempty"`
 }
 
-type TMConfig struct {
-	Disabled      bool
+type ServerConfig struct {
+	Enabled       bool
 	ListenAddress string
 }
 
 type V0Config struct {
-	Disabled bool
-	Server   *server.ServerConfig
+	Enabled bool
+	Server  *server.ServerConfig
 }
 
 type ProfilerConfig struct {
-	Disabled      bool
+	Enabled       bool
+	ListenAddress string
+}
+
+type GRPCConfig struct {
+	Enabled       bool
 	ListenAddress string
 }
 
@@ -28,23 +34,34 @@ func DefaultRPCConfig() *RPCConfig {
 		TM:       DefaultTMConfig(),
 		V0:       DefaultV0Config(),
 		Profiler: DefaultProfilerConfig(),
+		GRPC:     DefaultGRPCConfig(),
 	}
 }
+
 func DefaultV0Config() *V0Config {
 	return &V0Config{
-		Server: server.DefaultServerConfig(),
+		Enabled: true,
+		Server:  server.DefaultServerConfig(),
 	}
 }
 
-func DefaultTMConfig() *TMConfig {
-	return &TMConfig{
+func DefaultTMConfig() *ServerConfig {
+	return &ServerConfig{
+		Enabled:       true,
 		ListenAddress: "tcp://localhost:46657",
 	}
 }
 
-func DefaultProfilerConfig() *ProfilerConfig {
-	return &ProfilerConfig{
-		Disabled:      true,
+func DefaultGRPCConfig() *ServerConfig {
+	return &ServerConfig{
+		Enabled:       true,
+		ListenAddress: "localhost:10997",
+	}
+}
+
+func DefaultProfilerConfig() *ServerConfig {
+	return &ServerConfig{
+		Enabled:       false,
 		ListenAddress: "tcp://localhost:6060",
 	}
 }
diff --git a/rpc/result.go b/rpc/result.go
index 440a152aeb7928bcdb2544a35c93c060875e8b43..0de6909a798cfd266f6605ceb9342cdd44bd2fdf 100644
--- a/rpc/result.go
+++ b/rpc/result.go
@@ -19,6 +19,7 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	exe_events "github.com/hyperledger/burrow/execution/events"
 	evm_events "github.com/hyperledger/burrow/execution/evm/events"
@@ -74,7 +75,7 @@ type ResultGetBlock struct {
 type ResultStatus struct {
 	NodeInfo          p2p.NodeInfo
 	GenesisHash       []byte
-	PubKey            acm.PublicKey
+	PubKey            crypto.PublicKey
 	LatestBlockHash   []byte
 	LatestBlockHeight uint64
 	LatestBlockTime   int64
@@ -136,8 +137,8 @@ type ResultGetAccount struct {
 }
 
 type AccountHumanReadable struct {
-	Address     acm.Address
-	PublicKey   acm.PublicKey
+	Address     crypto.Address
+	PublicKey   crypto.PublicKey
 	Sequence    uint64
 	Balance     uint64
 	Code        []string
diff --git a/rpc/result_test.go b/rpc/result_test.go
index d275011305bb73617805140b91e324161e8cbf80..01c531e9527c79b94513c657c544073688d7caf0 100644
--- a/rpc/result_test.go
+++ b/rpc/result_test.go
@@ -19,6 +19,7 @@ import (
 	"testing"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/txs"
 	"github.com/stretchr/testify/assert"
@@ -31,7 +32,7 @@ func TestResultBroadcastTx(t *testing.T) {
 	// Make sure these are unpacked as expected
 	res := ResultBroadcastTx{
 		Receipt: txs.Receipt{
-			ContractAddress: acm.Address{0, 2, 3},
+			ContractAddress: crypto.Address{0, 2, 3},
 			CreatesContract: true,
 			TxHash:          []byte("foo"),
 		},
@@ -50,7 +51,7 @@ func TestListUnconfirmedTxs(t *testing.T) {
 		NumTxs: 3,
 		Txs: []txs.Wrapper{
 			txs.Wrap(&txs.CallTx{
-				Address: &acm.Address{1},
+				Address: &crypto.Address{1},
 			}),
 		},
 	}
diff --git a/rpc/service.go b/rpc/service.go
index 0ec8291cf95c88c3454bddc95f23e3ed04b4df54..415768f851caf0ca9d76252d6b344ddde20ec88c 100644
--- a/rpc/service.go
+++ b/rpc/service.go
@@ -23,6 +23,7 @@ import (
 	"github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/query"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/keys"
@@ -222,7 +223,7 @@ func (s *Service) Genesis() (*ResultGenesis, error) {
 }
 
 // Accounts
-func (s *Service) GetAccount(address acm.Address) (*ResultGetAccount, error) {
+func (s *Service) GetAccount(address crypto.Address) (*ResultGetAccount, error) {
 	acc, err := s.state.GetAccount(address)
 	if err != nil {
 		return nil, err
@@ -248,7 +249,7 @@ func (s *Service) ListAccounts(predicate func(acm.Account) bool) (*ResultListAcc
 	}, nil
 }
 
-func (s *Service) GetStorage(address acm.Address, key []byte) (*ResultGetStorage, error) {
+func (s *Service) GetStorage(address crypto.Address, key []byte) (*ResultGetStorage, error) {
 	account, err := s.state.GetAccount(address)
 	if err != nil {
 		return nil, err
@@ -267,7 +268,7 @@ func (s *Service) GetStorage(address acm.Address, key []byte) (*ResultGetStorage
 	return &ResultGetStorage{Key: key, Value: value.UnpadLeft()}, nil
 }
 
-func (s *Service) DumpStorage(address acm.Address) (*ResultDumpStorage, error) {
+func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error) {
 	account, err := s.state.GetAccount(address)
 	if err != nil {
 		return nil, err
@@ -286,7 +287,7 @@ func (s *Service) DumpStorage(address acm.Address) (*ResultDumpStorage, error) {
 	}, nil
 }
 
-func (s *Service) GetAccountHumanReadable(address acm.Address) (*ResultGetAccountHumanReadable, error) {
+func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAccountHumanReadable, error) {
 	acc, err := s.state.GetAccount(address)
 	if err != nil {
 		return nil, err
diff --git a/rpc/tm/client/client.go b/rpc/tm/client/client.go
index fffdeb72bbb1e3a5e55b605eb3dbc76a0750463f..773f34436402623306fe993425a245cb2f02c4af 100644
--- a/rpc/tm/client/client.go
+++ b/rpc/tm/client/client.go
@@ -19,6 +19,7 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/rpc/tm"
@@ -65,7 +66,7 @@ func GenPrivAccount(client RPCClient) (*rpc.ResultGeneratePrivateAccount, error)
 	return res, nil
 }
 
-func GetAccount(client RPCClient, address acm.Address) (acm.Account, error) {
+func GetAccount(client RPCClient, address crypto.Address) (acm.Account, error) {
 	res := new(rpc.ResultGetAccount)
 	_, err := client.Call(tm.GetAccount, pmap("address", address), res)
 	if err != nil {
@@ -87,7 +88,7 @@ func SignTx(client RPCClient, tx txs.Tx, privAccounts []*acm.ConcretePrivateAcco
 	return res.Tx, nil
 }
 
-func DumpStorage(client RPCClient, address acm.Address) (*rpc.ResultDumpStorage, error) {
+func DumpStorage(client RPCClient, address crypto.Address) (*rpc.ResultDumpStorage, error) {
 	res := new(rpc.ResultDumpStorage)
 	_, err := client.Call(tm.DumpStorage, pmap("address", address), res)
 	if err != nil {
@@ -96,7 +97,7 @@ func DumpStorage(client RPCClient, address acm.Address) (*rpc.ResultDumpStorage,
 	return res, nil
 }
 
-func GetStorage(client RPCClient, address acm.Address, key []byte) ([]byte, error) {
+func GetStorage(client RPCClient, address crypto.Address, key []byte) ([]byte, error) {
 	res := new(rpc.ResultGetStorage)
 	_, err := client.Call(tm.GetStorage, pmap("address", address, "key", key), res)
 	if err != nil {
@@ -105,7 +106,7 @@ func GetStorage(client RPCClient, address acm.Address, key []byte) ([]byte, erro
 	return res.Value, nil
 }
 
-func CallCode(client RPCClient, fromAddress acm.Address, code, data []byte) (*rpc.ResultCall, error) {
+func CallCode(client RPCClient, fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) {
 	res := new(rpc.ResultCall)
 	_, err := client.Call(tm.CallCode, pmap("fromAddress", fromAddress, "code", code, "data", data), res)
 	if err != nil {
@@ -114,7 +115,7 @@ func CallCode(client RPCClient, fromAddress acm.Address, code, data []byte) (*rp
 	return res, nil
 }
 
-func Call(client RPCClient, fromAddress, toAddress acm.Address, data []byte) (*rpc.ResultCall, error) {
+func Call(client RPCClient, fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) {
 	res := new(rpc.ResultCall)
 	_, err := client.Call(tm.Call, pmap("fromAddress", fromAddress, "toAddress", toAddress,
 		"data", data), res)
diff --git a/rpc/tm/integration/shared.go b/rpc/tm/integration/shared.go
index e9c1981f3554daaf5af1d065ac41d3db7b53ae62..ee6e0aee21a191ef05991780a1598cba415ea5b9 100644
--- a/rpc/tm/integration/shared.go
+++ b/rpc/tm/integration/shared.go
@@ -25,6 +25,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/core/integration"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/rpc"
 	tm_client "github.com/hyperledger/burrow/rpc/tm/client"
@@ -54,7 +55,7 @@ var (
 //-------------------------------------------------------------------------------
 // some default transaction functions
 
-func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr acm.Address, amt uint64) *txs.SendTx {
+func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr crypto.Address, amt uint64) *txs.SendTx {
 	sequence := getSequence(t, client, privateAccounts[0].Address())
 	tx := txs.NewSendTx()
 	tx.AddInputWithSequence(privateAccounts[0].PublicKey(), amt, sequence+1)
@@ -62,13 +63,13 @@ func makeDefaultSendTx(t *testing.T, client tm_client.RPCClient, addr acm.Addres
 	return tx
 }
 
-func makeDefaultSendTxSigned(t *testing.T, client tm_client.RPCClient, addr acm.Address, amt uint64) *txs.SendTx {
+func makeDefaultSendTxSigned(t *testing.T, client tm_client.RPCClient, addr crypto.Address, amt uint64) *txs.SendTx {
 	tx := makeDefaultSendTx(t, client, addr, amt)
 	require.NoError(t, tx.Sign(genesisDoc.ChainID(), privateAccounts[0]))
 	return tx
 }
 
-func makeDefaultCallTx(t *testing.T, client tm_client.RPCClient, addr *acm.Address, code []byte, amt, gasLim,
+func makeDefaultCallTx(t *testing.T, client tm_client.RPCClient, addr *crypto.Address, code []byte, amt, gasLim,
 	fee uint64) *txs.CallTx {
 	sequence := getSequence(t, client, privateAccounts[0].Address())
 	tx := txs.NewCallTxWithSequence(privateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee,
@@ -88,7 +89,7 @@ func makeDefaultNameTx(t *testing.T, client tm_client.RPCClient, name, value str
 // rpc call wrappers (fail on err)
 
 // get an account's sequence number
-func getSequence(t *testing.T, client tm_client.RPCClient, addr acm.Address) uint64 {
+func getSequence(t *testing.T, client tm_client.RPCClient, addr crypto.Address) uint64 {
 	acc, err := tm_client.GetAccount(client, addr)
 	if err != nil {
 		t.Fatal(err)
@@ -100,7 +101,7 @@ func getSequence(t *testing.T, client tm_client.RPCClient, addr acm.Address) uin
 }
 
 // get the account
-func getAccount(t *testing.T, client tm_client.RPCClient, addr acm.Address) acm.Account {
+func getAccount(t *testing.T, client tm_client.RPCClient, addr crypto.Address) acm.Account {
 	ac, err := tm_client.GetAccount(client, addr)
 	if err != nil {
 		t.Fatal(err)
@@ -126,7 +127,7 @@ func broadcastTx(t *testing.T, client tm_client.RPCClient, tx txs.Tx) *txs.Recei
 }
 
 // dump all storage for an account. currently unused
-func dumpStorage(t *testing.T, addr acm.Address) *rpc.ResultDumpStorage {
+func dumpStorage(t *testing.T, addr crypto.Address) *rpc.ResultDumpStorage {
 	client := clients["HTTP"]
 	resp, err := tm_client.DumpStorage(client, addr)
 	if err != nil {
@@ -135,7 +136,7 @@ func dumpStorage(t *testing.T, addr acm.Address) *rpc.ResultDumpStorage {
 	return resp
 }
 
-func getStorage(t *testing.T, client tm_client.RPCClient, addr acm.Address, key []byte) []byte {
+func getStorage(t *testing.T, client tm_client.RPCClient, addr crypto.Address, key []byte) []byte {
 	resp, err := tm_client.GetStorage(client, addr, key)
 	if err != nil {
 		t.Fatal(err)
@@ -143,7 +144,7 @@ func getStorage(t *testing.T, client tm_client.RPCClient, addr acm.Address, key
 	return resp
 }
 
-func callCode(t *testing.T, client tm_client.RPCClient, fromAddress acm.Address, code, data,
+func callCode(t *testing.T, client tm_client.RPCClient, fromAddress crypto.Address, code, data,
 	expected []byte) {
 	resp, err := tm_client.CallCode(client, fromAddress, code, data)
 	if err != nil {
@@ -156,7 +157,7 @@ func callCode(t *testing.T, client tm_client.RPCClient, fromAddress acm.Address,
 	}
 }
 
-func callContract(t *testing.T, client tm_client.RPCClient, fromAddress, toAddress acm.Address,
+func callContract(t *testing.T, client tm_client.RPCClient, fromAddress, toAddress crypto.Address,
 	data, expected []byte) {
 	resp, err := tm_client.Call(client, fromAddress, toAddress, data)
 	if err != nil {
@@ -209,7 +210,7 @@ func simpleContract() ([]byte, []byte, []byte) {
 }
 
 // simple call contract calls another contract
-func simpleCallContract(addr acm.Address) ([]byte, []byte, []byte) {
+func simpleCallContract(addr crypto.Address) ([]byte, []byte, []byte) {
 	gas1, gas2 := byte(0x1), byte(0x1)
 	value := byte(0x1)
 	inOff, inSize := byte(0x0), byte(0x0) // no call data
diff --git a/rpc/tm/integration/websocket_client_test.go b/rpc/tm/integration/websocket_client_test.go
index 00b3c7234ef9c89b517d20f8035dead41fca8a8b..d19e32fe4892600b08efff4315e27a34cecb3e49 100644
--- a/rpc/tm/integration/websocket_client_test.go
+++ b/rpc/tm/integration/websocket_client_test.go
@@ -23,7 +23,7 @@ import (
 	"testing"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	exe_events "github.com/hyperledger/burrow/execution/events"
 	evm_events "github.com/hyperledger/burrow/execution/evm/events"
 	"github.com/hyperledger/burrow/rpc"
@@ -171,7 +171,7 @@ func TestWSCallWait(t *testing.T) {
 	for i := 0; i < 20; i++ {
 		amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000)
 		code, returnCode, returnVal := simpleContract()
-		var contractAddr acm.Address
+		var contractAddr crypto.Address
 		eid1 := exe_events.EventStringAccountInput(privateAccounts[0].Address())
 		subId1 := subscribeAndGetSubscriptionId(t, wsc, eid1)
 		// wait for the contract to be created
diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go
index ea30de8f3aac27685c104ccff78aee33fc930fde..2df6cd390bfb4151cad5cbb092447ee39b9cf42c 100644
--- a/rpc/tm/integration/websocket_helpers.go
+++ b/rpc/tm/integration/websocket_helpers.go
@@ -25,7 +25,7 @@ import (
 	"testing"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/rpc"
 	tm_client "github.com/hyperledger/burrow/rpc/tm/client"
@@ -245,7 +245,7 @@ func readResponse(r rpctypes.RPCResponse) (*rpc.ResultEvent, error) {
 
 //--------------------------------------------------------------------------------
 
-func unmarshalValidateSend(amt uint64, toAddr acm.Address, resultEvent *rpc.ResultEvent) error {
+func unmarshalValidateSend(amt uint64, toAddr crypto.Address, resultEvent *rpc.ResultEvent) error {
 	data := resultEvent.EventDataTx
 	if data == nil {
 		return fmt.Errorf("event data %v is not EventDataTx", resultEvent)
@@ -294,7 +294,7 @@ func unmarshalValidateTx(amt uint64, returnCode []byte) resultEventChecker {
 	}
 }
 
-func unmarshalValidateCall(origin acm.Address, returnCode []byte, txid *[]byte) resultEventChecker {
+func unmarshalValidateCall(origin crypto.Address, returnCode []byte, txid *[]byte) resultEventChecker {
 	return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
 		data := resultEvent.EventDataCall
 		if data == nil {
diff --git a/rpc/tm/methods.go b/rpc/tm/methods.go
index 49e6696f68290258078e84e2ce6a3d3415caaf8a..4f54885aa390f78a11ce462e5c4bf8348a2e5382 100644
--- a/rpc/tm/methods.go
+++ b/rpc/tm/methods.go
@@ -6,6 +6,7 @@ import (
 	"time"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/logging"
@@ -79,7 +80,7 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*gorpc.R
 		}, "tx,privAccounts"),
 
 		// Simulated call
-		Call: gorpc.NewRPCFunc(func(fromAddress, toAddress acm.Address, data []byte) (*rpc.ResultCall, error) {
+		Call: gorpc.NewRPCFunc(func(fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) {
 			call, err := service.Transactor().Call(service.State(), fromAddress, toAddress, data)
 			if err != nil {
 				return nil, err
@@ -87,7 +88,7 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*gorpc.R
 			return &rpc.ResultCall{Call: *call}, nil
 		}, "fromAddress,toAddress,data"),
 
-		CallCode: gorpc.NewRPCFunc(func(fromAddress acm.Address, code, data []byte) (*rpc.ResultCall, error) {
+		CallCode: gorpc.NewRPCFunc(func(fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) {
 			call, err := service.Transactor().CallCode(service.State(), fromAddress, code, data)
 			if err != nil {
 				return nil, err
diff --git a/rpc/v0/codec_test.go b/rpc/v0/codec_test.go
index 5bd6d231906c9940e0484857ecca91267e1cb3ad..500afb1e5c8f8f8ab4adfb42da5c4ceb49bed822 100644
--- a/rpc/v0/codec_test.go
+++ b/rpc/v0/codec_test.go
@@ -17,22 +17,22 @@ package v0
 import (
 	"testing"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestKeysEncoding(t *testing.T) {
 	codec := NewTCodec()
-	privateKey := acm.PrivateKeyFromSecret("foo")
+	privateKey := crypto.PrivateKeyFromSecret("foo", crypto.CurveTypeEd25519)
 	type keyPair struct {
-		PrivateKey acm.PrivateKey
-		PublicKey  acm.PublicKey
+		PrivateKey crypto.PrivateKey
+		PublicKey  crypto.PublicKey
 	}
 
 	kp := keyPair{
 		PrivateKey: privateKey,
-		PublicKey:  privateKey.PublicKey(),
+		PublicKey:  privateKey.GetPublicKey(),
 	}
 
 	bs, err := codec.EncodeBytes(kp)
diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go
index 0226189e399ed8719d004732b9d0753f95f35232..3209b7f36952ac94608742f88236c1cbaa7f0487 100644
--- a/rpc/v0/methods.go
+++ b/rpc/v0/methods.go
@@ -18,6 +18,7 @@ import (
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/rpc"
@@ -97,7 +98,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.AddressFromBytes(param.Address)
+			address, err := crypto.AddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -113,7 +114,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.AddressFromBytes(param.Address)
+			address, err := crypto.AddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -129,7 +130,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.AddressFromBytes(param.Address)
+			address, err := crypto.AddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -165,11 +166,11 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			from, err := acm.AddressFromBytes(param.From)
+			from, err := crypto.AddressFromBytes(param.From)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.AddressFromBytes(param.Address)
+			address, err := crypto.AddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -185,7 +186,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			from, err := acm.AddressFromBytes(param.From)
+			from, err := crypto.AddressFromBytes(param.From)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -226,7 +227,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.MaybeAddressFromBytes(param.Address)
+			address, err := crypto.MaybeAddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -247,7 +248,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			address, err := acm.MaybeAddressFromBytes(param.Address)
+			address, err := crypto.MaybeAddressFromBytes(param.Address)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -267,7 +268,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			toAddress, err := acm.AddressFromBytes(param.ToAddress)
+			toAddress, err := crypto.AddressFromBytes(param.ToAddress)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -288,7 +289,7 @@ func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) m
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
-			toAddress, err := acm.AddressFromBytes(param.ToAddress)
+			toAddress, err := crypto.AddressFromBytes(param.ToAddress)
 			if err != nil {
 				return nil, rpc.INVALID_PARAMS, err
 			}
@@ -449,7 +450,7 @@ func signingAccount(accounts *execution.Accounts, inputAccount InputAccount) (*e
 		if len(inputAccount.PrivateKey) > 0 {
 			return nil, fmt.Errorf("privKey and address provided but only one or the other should be given")
 		}
-		address, err := acm.AddressFromBytes(inputAccount.Address)
+		address, err := crypto.AddressFromBytes(inputAccount.Address)
 		if err != nil {
 			return nil, err
 		}
diff --git a/rpc/v0/server/server.go b/rpc/v0/server/server.go
index 2ee096c5b2aef767c3d121c6a169888c94296a6d..ec4c89c2e8d7733ef4c5d0c16460780f22a7f4dc 100644
--- a/rpc/v0/server/server.go
+++ b/rpc/v0/server/server.go
@@ -63,8 +63,8 @@ type ServeProcess struct {
 
 // Initializes all the servers and starts listening for connections.
 func (serveProcess *ServeProcess) Start() error {
-	router := gin.New()
 	gin.SetMode(gin.ReleaseMode)
+	router := gin.New()
 	config := serveProcess.config
 
 	ch := NewCORSMiddleware(config.CORS)
diff --git a/txs/bond_tx.go b/txs/bond_tx.go
index aa6aecea7d64472134e3a87ce99f17f3ed5c3824..a7100ddf86f4094d5313f5288da10e5e63131d24 100644
--- a/txs/bond_tx.go
+++ b/txs/bond_tx.go
@@ -6,12 +6,13 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type BondTx struct {
-	PubKey    acm.PublicKey
-	Signature acm.Signature
+	PubKey    crypto.PublicKey
+	Signature crypto.Signature
 	Inputs    []*TxInput
 	UnbondTo  []*TxOutput
 	txHashMemoizer
@@ -19,7 +20,7 @@ type BondTx struct {
 
 var _ Tx = &BondTx{}
 
-func NewBondTx(pubkey acm.PublicKey) (*BondTx, error) {
+func NewBondTx(pubkey crypto.PublicKey) (*BondTx, error) {
 	return &BondTx{
 		PubKey:   pubkey,
 		Inputs:   []*TxInput{},
@@ -60,7 +61,7 @@ func (tx *BondTx) Hash(chainID string) []byte {
 	return tx.txHashMemoizer.hash(chainID, tx)
 }
 
-func (tx *BondTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uint64) error {
+func (tx *BondTx) AddInput(st state.AccountGetter, pubkey crypto.PublicKey, amt uint64) error {
 	addr := pubkey.Address()
 	acc, err := st.GetAccount(addr)
 	if err != nil {
@@ -72,7 +73,7 @@ func (tx *BondTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uin
 	return tx.AddInputWithSequence(pubkey, amt, acc.Sequence()+uint64(1))
 }
 
-func (tx *BondTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequence uint64) error {
+func (tx *BondTx) AddInputWithSequence(pubkey crypto.PublicKey, amt uint64, sequence uint64) error {
 	tx.Inputs = append(tx.Inputs, &TxInput{
 		Address:   pubkey.Address(),
 		Amount:    amt,
@@ -82,7 +83,7 @@ func (tx *BondTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc
 	return nil
 }
 
-func (tx *BondTx) AddOutput(addr acm.Address, amt uint64) error {
+func (tx *BondTx) AddOutput(addr crypto.Address, amt uint64) error {
 	tx.UnbondTo = append(tx.UnbondTo, &TxOutput{
 		Address: addr,
 		Amount:  amt,
@@ -96,13 +97,13 @@ func (tx *BondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner)
 			len(signingAccounts))
 	}
 	var err error
-	tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
 	for i := 1; i <= len(signingAccounts); i++ {
 		tx.Inputs[i].PublicKey = signingAccounts[i].PublicKey()
-		tx.Inputs[i].Signature, err = acm.ChainSign(signingAccounts[i], chainID, tx)
+		tx.Inputs[i].Signature, err = crypto.ChainSign(signingAccounts[i], chainID, tx)
 		if err != nil {
 			return fmt.Errorf("could not sign tx %v input %v: %v", tx, tx.Inputs[i], err)
 		}
diff --git a/txs/call_tx.go b/txs/call_tx.go
index a3d0f1b849db203f34c55739bfd827ede46af135..ebfdb6f49f05444c23e56278f9e087af2b788b61 100644
--- a/txs/call_tx.go
+++ b/txs/call_tx.go
@@ -6,13 +6,14 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type CallTx struct {
 	Input *TxInput
 	// Pointer since CallTx defines unset 'to' address as inducing account creation
-	Address  *acm.Address
+	Address  *crypto.Address
 	GasLimit uint64
 	Fee      uint64
 	Data     []byte
@@ -21,7 +22,7 @@ type CallTx struct {
 
 var _ Tx = &CallTx{}
 
-func NewCallTx(st state.AccountGetter, from acm.PublicKey, to *acm.Address, data []byte,
+func NewCallTx(st state.AccountGetter, from crypto.PublicKey, to *crypto.Address, data []byte,
 	amt, gasLimit, fee uint64) (*CallTx, error) {
 
 	addr := from.Address()
@@ -37,7 +38,7 @@ func NewCallTx(st state.AccountGetter, from acm.PublicKey, to *acm.Address, data
 	return NewCallTxWithSequence(from, to, data, amt, gasLimit, fee, sequence), nil
 }
 
-func NewCallTxWithSequence(from acm.PublicKey, to *acm.Address, data []byte,
+func NewCallTxWithSequence(from crypto.PublicKey, to *crypto.Address, data []byte,
 	amt, gasLimit, fee, sequence uint64) *CallTx {
 	input := &TxInput{
 		Address:   from.Address(),
@@ -62,7 +63,7 @@ func (tx *CallTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner)
 	}
 	var err error
 	tx.Input.PublicKey = signingAccounts[0].PublicKey()
-	tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
diff --git a/txs/go_wire_codec_test.go b/txs/go_wire_codec_test.go
index 7e191c19e6d5818b296064b27cda244780ddea9f..4b4dd579ef4d1926d84bdd638ea37b23541f5350 100644
--- a/txs/go_wire_codec_test.go
+++ b/txs/go_wire_codec_test.go
@@ -3,21 +3,23 @@ package txs
 import (
 	"testing"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestEncodeTxDecodeTx(t *testing.T) {
 	gwc := NewGoWireCodec()
-	inputAddress := acm.Address{1, 2, 3, 4, 5}
-	outputAddress := acm.Address{5, 4, 3, 2, 1}
+	inputAddress := crypto.Address{1, 2, 3, 4, 5}
+	outputAddress := crypto.Address{5, 4, 3, 2, 1}
 	amount := uint64(2)
 	sequence := uint64(3)
 	tx := &SendTx{
 		Inputs: []*TxInput{{
-			Address:  inputAddress,
-			Amount:   amount,
-			Sequence: sequence,
+			Address:   inputAddress,
+			Amount:    amount,
+			Sequence:  sequence,
+			PublicKey: crypto.PublicKey{PublicKey: []byte{0}},
+			Signature: crypto.Signature{Signature: []byte{0}},
 		}},
 		Outputs: []*TxOutput{{
 			Address: outputAddress,
@@ -35,14 +37,16 @@ func TestEncodeTxDecodeTx(t *testing.T) {
 
 func TestEncodeTxDecodeTx_CallTx(t *testing.T) {
 	gwc := NewGoWireCodec()
-	inputAddress := acm.Address{1, 2, 3, 4, 5}
+	inputAddress := crypto.Address{1, 2, 3, 4, 5}
 	amount := uint64(2)
 	sequence := uint64(3)
 	tx := &CallTx{
 		Input: &TxInput{
-			Address:  inputAddress,
-			Amount:   amount,
-			Sequence: sequence,
+			Address:   inputAddress,
+			Amount:    amount,
+			Sequence:  sequence,
+			PublicKey: crypto.PublicKey{PublicKey: []byte{0}},
+			Signature: crypto.Signature{Signature: []byte{0}},
 		},
 		GasLimit: 233,
 		Fee:      2,
diff --git a/txs/name_tx.go b/txs/name_tx.go
index 76ef57dceb4b4d568e1f5da46d9ce5d4575e5480..d16ff0d1c026da67fa7052433d451595b05518e0 100644
--- a/txs/name_tx.go
+++ b/txs/name_tx.go
@@ -8,6 +8,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
@@ -26,7 +27,7 @@ type NameTx struct {
 
 var _ Tx = &NameTx{}
 
-func NewNameTx(st state.AccountGetter, from acm.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) {
+func NewNameTx(st state.AccountGetter, from crypto.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) {
 	addr := from.Address()
 	acc, err := st.GetAccount(addr)
 	if err != nil {
@@ -40,7 +41,7 @@ func NewNameTx(st state.AccountGetter, from acm.PublicKey, name, data string, am
 	return NewNameTxWithSequence(from, name, data, amt, fee, sequence), nil
 }
 
-func NewNameTxWithSequence(from acm.PublicKey, name, data string, amt, fee, sequence uint64) *NameTx {
+func NewNameTxWithSequence(from crypto.PublicKey, name, data string, amt, fee, sequence uint64) *NameTx {
 	input := &TxInput{
 		Address:   from.Address(),
 		Amount:    amt,
@@ -63,7 +64,7 @@ func (tx *NameTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner)
 	}
 	var err error
 	tx.Input.PublicKey = signingAccounts[0].PublicKey()
-	tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
diff --git a/txs/permission_tx.go b/txs/permission_tx.go
index c2dad89bf1750cd35ab217fa613e591ce64305f1..2ec99eb81d921810594f1feeffaeab554eeb4109 100644
--- a/txs/permission_tx.go
+++ b/txs/permission_tx.go
@@ -6,6 +6,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission/snatives"
 	"github.com/tendermint/go-wire"
 )
@@ -18,7 +19,7 @@ type PermissionsTx struct {
 
 var _ Tx = &PermissionsTx{}
 
-func NewPermissionsTx(st state.AccountGetter, from acm.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) {
+func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) {
 	addr := from.Address()
 	acc, err := st.GetAccount(addr)
 	if err != nil {
@@ -32,7 +33,7 @@ func NewPermissionsTx(st state.AccountGetter, from acm.PublicKey, args snatives.
 	return NewPermissionsTxWithSequence(from, args, sequence), nil
 }
 
-func NewPermissionsTxWithSequence(from acm.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx {
+func NewPermissionsTxWithSequence(from crypto.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx {
 	input := &TxInput{
 		Address:   from.Address(),
 		Amount:    1, // NOTE: amounts can't be 0 ...
@@ -53,7 +54,7 @@ func (tx *PermissionsTx) Sign(chainID string, signingAccounts ...acm.Addressable
 	}
 	var err error
 	tx.Input.PublicKey = signingAccounts[0].PublicKey()
-	tx.Input.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Input.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
diff --git a/txs/rebond_tx.go b/txs/rebond_tx.go
index b5b22ff4b0f87e123b6b7101f2049b28d47405e5..8816937d18f67fc7a8713947e0e78c22204e1bb8 100644
--- a/txs/rebond_tx.go
+++ b/txs/rebond_tx.go
@@ -5,19 +5,20 @@ import (
 	"io"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type RebondTx struct {
-	Address   acm.Address
+	Address   crypto.Address
 	Height    int
-	Signature acm.Signature
+	Signature crypto.Signature
 	txHashMemoizer
 }
 
 var _ Tx = &RebondTx{}
 
-func NewRebondTx(addr acm.Address, height int) *RebondTx {
+func NewRebondTx(addr crypto.Address, height int) *RebondTx {
 	return &RebondTx{
 		Address: addr,
 		Height:  height,
@@ -30,7 +31,7 @@ func (tx *RebondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigne
 			len(signingAccounts))
 	}
 	var err error
-	tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
diff --git a/txs/send_tx.go b/txs/send_tx.go
index e9212fd8042ff5511a643b6b2ea7c32a94065978..421d9f190e2d75fdca637d0b7a686409d7a78833 100644
--- a/txs/send_tx.go
+++ b/txs/send_tx.go
@@ -6,6 +6,7 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
@@ -55,7 +56,7 @@ func (tx *SendTx) Hash(chainID string) []byte {
 	return tx.txHashMemoizer.hash(chainID, tx)
 }
 
-func (tx *SendTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uint64) error {
+func (tx *SendTx) AddInput(st state.AccountGetter, pubkey crypto.PublicKey, amt uint64) error {
 	addr := pubkey.Address()
 	acc, err := st.GetAccount(addr)
 	if err != nil {
@@ -67,7 +68,7 @@ func (tx *SendTx) AddInput(st state.AccountGetter, pubkey acm.PublicKey, amt uin
 	return tx.AddInputWithSequence(pubkey, amt, acc.Sequence()+1)
 }
 
-func (tx *SendTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequence uint64) error {
+func (tx *SendTx) AddInputWithSequence(pubkey crypto.PublicKey, amt uint64, sequence uint64) error {
 	addr := pubkey.Address()
 	tx.Inputs = append(tx.Inputs, &TxInput{
 		Address:   addr,
@@ -78,7 +79,7 @@ func (tx *SendTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc
 	return nil
 }
 
-func (tx *SendTx) AddOutput(addr acm.Address, amt uint64) error {
+func (tx *SendTx) AddOutput(addr crypto.Address, amt uint64) error {
 	tx.Outputs = append(tx.Outputs, &TxOutput{
 		Address: addr,
 		Amount:  amt,
@@ -94,7 +95,7 @@ func (tx *SendTx) Sign(chainID string, signingAccounts ...acm.AddressableSigner)
 	var err error
 	for i, signingAccount := range signingAccounts {
 		tx.Inputs[i].PublicKey = signingAccount.PublicKey()
-		tx.Inputs[i].Signature, err = acm.ChainSign(signingAccount, chainID, tx)
+		tx.Inputs[i].Signature, err = crypto.ChainSign(signingAccount, chainID, tx)
 		if err != nil {
 			return fmt.Errorf("could not sign tx %v input %v: %v", tx, tx.Inputs[i], err)
 		}
diff --git a/txs/tx.go b/txs/tx.go
index dec958e22c3f19420a819d81a2f0e10d795bc2f8..e20292ef1f2f0e126b1a03ee8dc33013033453bd 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -21,6 +21,7 @@ import (
 	"io"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire/data"
 	"golang.org/x/crypto/ripemd160"
 )
@@ -99,7 +100,7 @@ type Decoder interface {
 type Receipt struct {
 	TxHash          []byte
 	CreatesContract bool
-	ContractAddress acm.Address
+	ContractAddress crypto.Address
 }
 
 type Wrapper struct {
@@ -153,7 +154,7 @@ func (thm *txHashMemoizer) hash(chainID string, tx Tx) []byte {
 }
 
 func TxHash(chainID string, tx Tx) []byte {
-	signBytes := acm.SignBytes(chainID, tx)
+	signBytes := crypto.SignBytes(chainID, tx)
 	hasher := ripemd160.New()
 	hasher.Write(signBytes)
 	// Calling Sum(nil) just gives us the digest with nothing prefixed
@@ -167,7 +168,7 @@ func GenerateReceipt(chainId string, tx Tx) Receipt {
 	if callTx, ok := tx.(*CallTx); ok {
 		receipt.CreatesContract = callTx.Address == nil
 		if receipt.CreatesContract {
-			receipt.ContractAddress = acm.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence)
+			receipt.ContractAddress = crypto.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence)
 		} else {
 			receipt.ContractAddress = *callTx.Address
 		}
diff --git a/txs/tx_input.go b/txs/tx_input.go
index 8ed9059da1b7d1827b310f8b0b58a77c1ea6ef1d..b8d4d4a974ffb741bf2234699bdb6ad81a7aeffa 100644
--- a/txs/tx_input.go
+++ b/txs/tx_input.go
@@ -4,16 +4,16 @@ import (
 	"fmt"
 	"io"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type TxInput struct {
-	Address   acm.Address
+	Address   crypto.Address
 	Amount    uint64
 	Sequence  uint64
-	Signature acm.Signature
-	PublicKey acm.PublicKey
+	Signature crypto.Signature
+	PublicKey crypto.PublicKey
 }
 
 func (txIn *TxInput) ValidateBasic() error {
diff --git a/txs/tx_output.go b/txs/tx_output.go
index 79c17b4953aa5e7ba4c41119e6c7546f4dd8c5a3..7467d29b13d6f511099d02388cf521b2dc0f06bd 100644
--- a/txs/tx_output.go
+++ b/txs/tx_output.go
@@ -4,12 +4,12 @@ import (
 	"fmt"
 	"io"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type TxOutput struct {
-	Address acm.Address
+	Address crypto.Address
 	Amount  uint64
 }
 
diff --git a/txs/tx_test.go b/txs/tx_test.go
index 73c7da8e113baae7ef6f6ad8a45cbf85185dd5d9..44f9892a73027b41bfc6be9a7c70b13ffbd31023 100644
--- a/txs/tx_test.go
+++ b/txs/tx_test.go
@@ -21,6 +21,7 @@ import (
 	"encoding/json"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	ptypes "github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/permission/snatives"
 	"github.com/stretchr/testify/assert"
@@ -29,7 +30,7 @@ import (
 
 var chainID = "myChainID"
 
-func makeAddress(str string) (address acm.Address) {
+func makeAddress(str string) (address crypto.Address) {
 	copy(address[:], ([]byte)(str))
 	return
 }
@@ -59,7 +60,7 @@ func TestSendTxSignable(t *testing.T) {
 			},
 		},
 	}
-	signBytes := acm.SignBytes(chainID, sendTx)
+	signBytes := crypto.SignBytes(chainID, sendTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[1,{"inputs":[{"address":"%s","amount":12345,"sequence":67890},{"address":"%s","amount":111,"sequence":222}],"outputs":[{"address":"%s","amount":333},{"address":"%s","amount":444}]}]}`,
 		chainID, sendTx.Inputs[0].Address.String(), sendTx.Inputs[1].Address.String(), sendTx.Outputs[0].Address.String(), sendTx.Outputs[1].Address.String())
@@ -82,7 +83,7 @@ func TestCallTxSignable(t *testing.T) {
 		Fee:      222,
 		Data:     []byte("data1"),
 	}
-	signBytes := acm.SignBytes(chainID, callTx)
+	signBytes := crypto.SignBytes(chainID, callTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[2,{"address":"%s","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"%s","amount":12345,"sequence":67890}}]}`,
 		chainID, callTx.Address.String(), callTx.Input.Address.String())
@@ -102,7 +103,7 @@ func TestNameTxSignable(t *testing.T) {
 		Data: "secretly.not.google.com",
 		Fee:  1000,
 	}
-	signBytes := acm.SignBytes(chainID, nameTx)
+	signBytes := crypto.SignBytes(chainID, nameTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[3,{"data":"secretly.not.google.com","fee":1000,"input":{"address":"%s","amount":12345,"sequence":250},"name":"google.com"}]}`,
 		chainID, nameTx.Input.Address.String())
@@ -141,7 +142,7 @@ func TestBondTxSignable(t *testing.T) {
 	expected := fmt.Sprintf(`{"chain_id":"%s",`+
 		`"tx":[17,{"inputs":[{"address":"%s",`+
 		`"amount":12345,"sequence":67890},{"address":"%s",`+
-		`"amount":111,"sequence":222}],"pub_key":[1,"%X"],`+
+		`"amount":111,"sequence":222}],"pub_key":{"CurveType":1,"PublicKey":"%X"},`+
 		`"unbond_to":[{"address":"%s",`+
 		`"amount":333},{"address":"%s",`+
 		`"amount":444}]}]}`,
@@ -152,7 +153,7 @@ func TestBondTxSignable(t *testing.T) {
 		bondTx.UnbondTo[0].Address.String(),
 		bondTx.UnbondTo[1].Address.String())
 
-	assert.Equal(t, expected, string(acm.SignBytes(chainID, bondTx)), "Unexpected sign string for BondTx")
+	assert.Equal(t, expected, string(crypto.SignBytes(chainID, bondTx)), "Unexpected sign string for BondTx")
 }
 
 func TestUnbondTxSignable(t *testing.T) {
@@ -160,7 +161,7 @@ func TestUnbondTxSignable(t *testing.T) {
 		Address: makeAddress("address1"),
 		Height:  111,
 	}
-	signBytes := acm.SignBytes(chainID, unbondTx)
+	signBytes := crypto.SignBytes(chainID, unbondTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[18,{"address":"%s","height":111}]}`,
 		chainID, unbondTx.Address.String())
@@ -174,7 +175,7 @@ func TestRebondTxSignable(t *testing.T) {
 		Address: makeAddress("address1"),
 		Height:  111,
 	}
-	signBytes := acm.SignBytes(chainID, rebondTx)
+	signBytes := crypto.SignBytes(chainID, rebondTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[19,{"address":"%s","height":111}]}`,
 		chainID, rebondTx.Address.String())
@@ -193,7 +194,7 @@ func TestPermissionsTxSignable(t *testing.T) {
 		PermArgs: snatives.SetBaseArgs(makeAddress("address1"), 1, true),
 	}
 
-	signBytes := acm.SignBytes(chainID, permsTx)
+	signBytes := crypto.SignBytes(chainID, permsTx)
 	signStr := string(signBytes)
 	expected := fmt.Sprintf(`{"chain_id":"%s","tx":[31,{"args":"{"PermFlag":%v,"Address":"%s","Permission":1,"Value":true}","input":{"address":"%s","amount":12345,"sequence":250}}]}`,
 		chainID, ptypes.SetBase, permsTx.PermArgs.Address.String(), permsTx.Input.Address.String())
@@ -219,10 +220,10 @@ func TestTxWrapper_MarshalJSON(t *testing.T) {
 }
 
 func TestNewPermissionsTxWithSequence(t *testing.T) {
-	privateKey := acm.PrivateKeyFromSecret("Shhh...")
+	privateKey := crypto.PrivateKeyFromSecret("Shhh...", crypto.CurveTypeEd25519)
 
-	args := snatives.SetBaseArgs(privateKey.PublicKey().Address(), ptypes.HasRole, true)
-	permTx := NewPermissionsTxWithSequence(privateKey.PublicKey(), args, 1)
+	args := snatives.SetBaseArgs(privateKey.GetPublicKey().Address(), ptypes.HasRole, true)
+	permTx := NewPermissionsTxWithSequence(privateKey.GetPublicKey(), args, 1)
 	testTxMarshalJSON(t, permTx)
 }
 
diff --git a/txs/unbond_tx.go b/txs/unbond_tx.go
index 786530295ff2596aea475ea8b534953fa53d0986..850de4f5266c15d5fc4a318f45092587d013ff3a 100644
--- a/txs/unbond_tx.go
+++ b/txs/unbond_tx.go
@@ -5,19 +5,20 @@ import (
 	"io"
 
 	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/crypto"
 	"github.com/tendermint/go-wire"
 )
 
 type UnbondTx struct {
-	Address   acm.Address
+	Address   crypto.Address
 	Height    int
-	Signature acm.Signature
+	Signature crypto.Signature
 	txHashMemoizer
 }
 
 var _ Tx = &UnbondTx{}
 
-func NewUnbondTx(addr acm.Address, height int) *UnbondTx {
+func NewUnbondTx(addr crypto.Address, height int) *UnbondTx {
 	return &UnbondTx{
 		Address: addr,
 		Height:  height,
@@ -30,7 +31,7 @@ func (tx *UnbondTx) Sign(chainID string, signingAccounts ...acm.AddressableSigne
 			len(signingAccounts))
 	}
 	var err error
-	tx.Signature, err = acm.ChainSign(signingAccounts[0], chainID, tx)
+	tx.Signature, err = crypto.ChainSign(signingAccounts[0], chainID, tx)
 	if err != nil {
 		return fmt.Errorf("could not sign %v: %v", tx, err)
 	}
diff --git a/vendor/github.com/howeyc/gopass/LICENSE.txt b/vendor/github.com/howeyc/gopass/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..14f74708a4a288be1f5d13c72ac7604abffd1e77
--- /dev/null
+++ b/vendor/github.com/howeyc/gopass/LICENSE.txt
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2012 Chris Howey
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/vendor/github.com/howeyc/gopass/pass.go b/vendor/github.com/howeyc/gopass/pass.go
new file mode 100644
index 0000000000000000000000000000000000000000..f5bd5a51a8c6888d7a2ac37946ed036f35dc7088
--- /dev/null
+++ b/vendor/github.com/howeyc/gopass/pass.go
@@ -0,0 +1,110 @@
+package gopass
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+)
+
+type FdReader interface {
+	io.Reader
+	Fd() uintptr
+}
+
+var defaultGetCh = func(r io.Reader) (byte, error) {
+	buf := make([]byte, 1)
+	if n, err := r.Read(buf); n == 0 || err != nil {
+		if err != nil {
+			return 0, err
+		}
+		return 0, io.EOF
+	}
+	return buf[0], nil
+}
+
+var (
+	maxLength            = 512
+	ErrInterrupted       = errors.New("interrupted")
+	ErrMaxLengthExceeded = fmt.Errorf("maximum byte limit (%v) exceeded", maxLength)
+
+	// Provide variable so that tests can provide a mock implementation.
+	getch = defaultGetCh
+)
+
+// getPasswd returns the input read from terminal.
+// If prompt is not empty, it will be output as a prompt to the user
+// If masked is true, typing will be matched by asterisks on the screen.
+// Otherwise, typing will echo nothing.
+func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) {
+	var err error
+	var pass, bs, mask []byte
+	if masked {
+		bs = []byte("\b \b")
+		mask = []byte("*")
+	}
+
+	if isTerminal(r.Fd()) {
+		if oldState, err := makeRaw(r.Fd()); err != nil {
+			return pass, err
+		} else {
+			defer func() {
+				restore(r.Fd(), oldState)
+				fmt.Fprintln(w)
+			}()
+		}
+	}
+
+	if prompt != "" {
+		fmt.Fprint(w, prompt)
+	}
+
+	// Track total bytes read, not just bytes in the password.  This ensures any
+	// errors that might flood the console with nil or -1 bytes infinitely are
+	// capped.
+	var counter int
+	for counter = 0; counter <= maxLength; counter++ {
+		if v, e := getch(r); e != nil {
+			err = e
+			break
+		} else if v == 127 || v == 8 {
+			if l := len(pass); l > 0 {
+				pass = pass[:l-1]
+				fmt.Fprint(w, string(bs))
+			}
+		} else if v == 13 || v == 10 {
+			break
+		} else if v == 3 {
+			err = ErrInterrupted
+			break
+		} else if v != 0 {
+			pass = append(pass, v)
+			fmt.Fprint(w, string(mask))
+		}
+	}
+
+	if counter > maxLength {
+		err = ErrMaxLengthExceeded
+	}
+
+	return pass, err
+}
+
+// GetPasswd returns the password read from the terminal without echoing input.
+// The returned byte array does not include end-of-line characters.
+func GetPasswd() ([]byte, error) {
+	return getPasswd("", false, os.Stdin, os.Stdout)
+}
+
+// GetPasswdMasked returns the password read from the terminal, echoing asterisks.
+// The returned byte array does not include end-of-line characters.
+func GetPasswdMasked() ([]byte, error) {
+	return getPasswd("", true, os.Stdin, os.Stdout)
+}
+
+// GetPasswdPrompt prompts the user and returns the password read from the terminal.
+// If mask is true, then asterisks are echoed.
+// The returned byte array does not include end-of-line characters.
+func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) {
+	return getPasswd(prompt, mask, r, w)
+}
diff --git a/vendor/github.com/howeyc/gopass/terminal.go b/vendor/github.com/howeyc/gopass/terminal.go
new file mode 100644
index 0000000000000000000000000000000000000000..083564146238fce92ac639cb0170edd023218748
--- /dev/null
+++ b/vendor/github.com/howeyc/gopass/terminal.go
@@ -0,0 +1,25 @@
+// +build !solaris
+
+package gopass
+
+import "golang.org/x/crypto/ssh/terminal"
+
+type terminalState struct {
+	state *terminal.State
+}
+
+func isTerminal(fd uintptr) bool {
+	return terminal.IsTerminal(int(fd))
+}
+
+func makeRaw(fd uintptr) (*terminalState, error) {
+	state, err := terminal.MakeRaw(int(fd))
+
+	return &terminalState{
+		state: state,
+	}, err
+}
+
+func restore(fd uintptr, oldState *terminalState) error {
+	return terminal.Restore(int(fd), oldState.state)
+}
diff --git a/vendor/github.com/howeyc/gopass/terminal_solaris.go b/vendor/github.com/howeyc/gopass/terminal_solaris.go
new file mode 100644
index 0000000000000000000000000000000000000000..257e1b4e81ea5bd163566588849f5533082fc0c3
--- /dev/null
+++ b/vendor/github.com/howeyc/gopass/terminal_solaris.go
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+// Below is derived from Solaris source, so CDDL license is included.
+
+package gopass
+
+import (
+	"syscall"
+
+	"golang.org/x/sys/unix"
+)
+
+type terminalState struct {
+	state *unix.Termios
+}
+
+// isTerminal returns true if there is a terminal attached to the given
+// file descriptor.
+// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
+func isTerminal(fd uintptr) bool {
+	var termio unix.Termio
+	err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
+	return err == nil
+}
+
+// makeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
+func makeRaw(fd uintptr) (*terminalState, error) {
+	oldTermiosPtr, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+	oldTermios := *oldTermiosPtr
+
+	newTermios := oldTermios
+	newTermios.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL
+	if err := unix.IoctlSetTermios(int(fd), unix.TCSETS, &newTermios); err != nil {
+		return nil, err
+	}
+
+	return &terminalState{
+		state: oldTermiosPtr,
+	}, nil
+}
+
+func restore(fd uintptr, oldState *terminalState) error {
+	return unix.IoctlSetTermios(int(fd), unix.TCSETS, oldState.state)
+}
diff --git a/vendor/github.com/wayn3h0/go-uuid/LICENSE b/vendor/github.com/wayn3h0/go-uuid/LICENSE
deleted file mode 100644
index fad0aa6350da088c679b81e73dee76ef873491da..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2015 Wayne Ho.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/github.com/wayn3h0/go-uuid/domain.go b/vendor/github.com/wayn3h0/go-uuid/domain.go
deleted file mode 100644
index ce09399bcae3b33d13fd12648d20594b9952530a..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/domain.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package uuid
-
-import (
-	"github.com/wayn3h0/go-uuid/internal/dcesecurity"
-)
-
-// Domain represents the identifier for a local domain
-type Domain byte
-
-// Domains.
-const (
-	DomainUser  = Domain(dcesecurity.User)  // POSIX UID domain
-	DomainGroup = Domain(dcesecurity.Group) // POSIX GID domain
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go b/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go
deleted file mode 100644
index 9de07243d9483e479daa7cf6be52b36496d90cf7..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/dcesecurity.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package dcesecurity
-
-import (
-	"encoding/binary"
-	"errors"
-	"os"
-
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/timebased"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-// Generate returns a new DCE security uuid.
-func New(domain Domain) ([]byte, error) {
-	uuid, err := timebased.New()
-	if err != nil {
-		return nil, err
-	}
-
-	switch domain {
-	case User:
-		uid := os.Getuid()
-		binary.BigEndian.PutUint32(uuid[0:], uint32(uid)) // network byte order
-	case Group:
-		gid := os.Getgid()
-		binary.BigEndian.PutUint32(uuid[0:], uint32(gid)) // network byte order
-	default:
-		return nil, errors.New("uuid: domain is invalid")
-	}
-
-	// set version(v2)
-	version.Set(uuid, version.DCESecurity)
-	// set layout(RFC4122)
-	layout.Set(uuid, layout.RFC4122)
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go b/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go
deleted file mode 100644
index 38eae8301fdb4a49fe10e50b74ef64a666919a51..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/dcesecurity/domain.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package dcesecurity
-
-// Domain represents the identifier for a local domain
-type Domain byte
-
-const (
-	User  Domain = iota + 1 // POSIX UID domain
-	Group                   // POSIX GID domain
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go b/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go
deleted file mode 100644
index 65a84cc463e4e429bbcea37024c1cffc56859daa..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/layout/layout.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package layout
-
-// Layout represents the layout of UUID. See page 5 in RFC 4122.
-type Layout byte
-
-const (
-	Invalid   Layout = iota // Invalid
-	NCS                     // Reserved, NCS backward compatibility. (Values: 0x00-0x07)
-	RFC4122                 // The variant specified in RFC 4122. (Values: 0x08-0x0b)
-	Microsoft               // Reserved, Microsoft Corporation backward compatibility. (Values: 0x0c-0x0d)
-	Future                  // Reserved for future definition. (Values: 0x0e-0x0f)
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go b/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go
deleted file mode 100644
index 7c5fde7beb4acd4386126cbbe93e5cf8040e8b67..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/layout/utility.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package layout
-
-// Set sets the layout for uuid.
-func Set(uuid []byte, layout Layout) {
-	switch layout {
-	case NCS:
-		uuid[8] = (uuid[8] | 0x00) & 0x0f // Msb0=0
-	case RFC4122:
-		uuid[8] = (uuid[8] | 0x80) & 0x8f // Msb0=1, Msb1=0
-	case Microsoft:
-		uuid[8] = (uuid[8] | 0xc0) & 0xcf // Msb0=1, Msb1=1, Msb2=0
-	case Future:
-		uuid[8] = (uuid[8] | 0xe0) & 0xef // Msb0=1, Msb1=1, Msb2=1
-	default:
-		panic("uuid: layout is invalid")
-	}
-}
-
-// Get returns layout of uuid.
-func Get(uuid []byte) Layout {
-	switch {
-	case (uuid[8] & 0x80) == 0x00:
-		return NCS
-	case (uuid[8] & 0xc0) == 0x80:
-		return RFC4122
-	case (uuid[8] & 0xe0) == 0xc0:
-		return Microsoft
-	case (uuid[8] & 0xe0) == 0xe0:
-		return Future
-	}
-
-	return Invalid
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go
deleted file mode 100644
index a03e6c71d68cd9f10cbe6591af938122ed803e71..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/md5/md5.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package md5
-
-import (
-	"crypto/md5"
-
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-// New returns a new name-based uses SHA-1 hashing uuid.
-func New(namespace, name string) ([]byte, error) {
-	hash := md5.New()
-	_, err := hash.Write([]byte(namespace))
-	if err != nil {
-		return nil, err
-	}
-	_, err = hash.Write([]byte(name))
-	if err != nil {
-		return nil, err
-	}
-
-	sum := hash.Sum(nil)
-
-	uuid := make([]byte, 16)
-	copy(uuid, sum)
-
-	// set version(v3)
-	version.Set(uuid, version.NameBasedMD5)
-	// set layout(RFC4122)
-	layout.Set(uuid, layout.RFC4122)
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go
deleted file mode 100644
index f4202676ad56349cf0dee76ef3adae53805f2b66..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/namebased.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package namebased
-
-// Standard Namespaces
-const (
-	NamespaceDNS  = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceURL  = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceOID  = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceX500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go b/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go
deleted file mode 100644
index 14a8eeb01c607720d0b2acfb230f3dc431e2d629..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/namebased/sha1/sha1.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package sha1
-
-import (
-	"crypto/sha1"
-
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-// New returns a new name-based uses SHA-1 hashing uuid.
-func New(namespace, name string) ([]byte, error) {
-	hash := sha1.New()
-	_, err := hash.Write([]byte(namespace))
-	if err != nil {
-		return nil, err
-	}
-	_, err = hash.Write([]byte(name))
-	if err != nil {
-		return nil, err
-	}
-
-	sum := hash.Sum(nil)
-
-	uuid := make([]byte, 16)
-	copy(uuid, sum)
-
-	// set version(v5)
-	version.Set(uuid, version.NameBasedSHA1)
-	// set layout(RFC4122)
-	layout.Set(uuid, layout.RFC4122)
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go b/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go
deleted file mode 100644
index 59354280800f18125241c15b9e941198ff2cc0e8..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/random/random.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package random
-
-import (
-	"crypto/rand"
-
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-// New returns a new randomly uuid.
-func New() ([]byte, error) {
-	uuid := make([]byte, 16)
-	n, err := rand.Read(uuid[:])
-	if err != nil {
-		return nil, err
-	}
-	if n != len(uuid) {
-		return nil, err
-	}
-
-	// set version(v4)
-	version.Set(uuid, version.Random)
-	// set layout(RFC4122)
-	layout.Set(uuid, layout.RFC4122)
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go b/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go
deleted file mode 100644
index 43541567cf1eaf24fdc4df388608f316e51da635..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/timebased/timebased.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package timebased
-
-import (
-	"crypto/rand"
-	"encoding/binary"
-	"net"
-	"sync"
-	"time"
-
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-const (
-	// Intervals bewteen 1/1/1970 and 15/10/1582 (Julain days of 1 Jan 1970 - Julain days of 15 Oct 1582) * 100-Nanoseconds Per Day
-	intervals = (2440587 - 2299160) * 86400 * 10000000
-)
-
-var (
-	lastGenerated time.Time  // last generated time
-	clockSequence uint16     // clock sequence for same tick
-	nodeID        []byte     // node id (MAC Address)
-	locker        sync.Mutex // global lock
-)
-
-// New returns a new time-based uuid.
-func New() ([]byte, error) {
-	// Get and release a global lock
-	locker.Lock()
-	defer locker.Unlock()
-
-	uuid := make([]byte, 16)
-
-	// get timestamp
-	now := time.Now().UTC()
-	timestamp := uint64(now.UnixNano()/100) + intervals // get timestamp
-	if !now.After(lastGenerated) {
-		clockSequence++ // last generated time known, then just increment clock sequence
-	} else {
-		b := make([]byte, 2)
-		_, err := rand.Read(b)
-		if err != nil {
-			return nil, err
-		}
-		clockSequence = uint16(int(b[0])<<8 | int(b[1])) // set to a random value (network byte order)
-	}
-
-	lastGenerated = now // remember the last generated time
-
-	timeLow := uint32(timestamp & 0xffffffff)
-	timeMiddle := uint16((timestamp >> 32) & 0xffff)
-	timeHigh := uint16((timestamp >> 48) & 0xfff)
-
-	// network byte order(BigEndian)
-	binary.BigEndian.PutUint32(uuid[0:], timeLow)
-	binary.BigEndian.PutUint16(uuid[4:], timeMiddle)
-	binary.BigEndian.PutUint16(uuid[6:], timeHigh)
-	binary.BigEndian.PutUint16(uuid[8:], clockSequence)
-
-	// get node id(mac address)
-	if nodeID == nil {
-		interfaces, err := net.Interfaces()
-		if err != nil {
-			return nil, err
-		}
-
-		for _, i := range interfaces {
-			if len(i.HardwareAddr) >= 6 {
-				nodeID = make([]byte, 6)
-				copy(nodeID, i.HardwareAddr)
-				break
-			}
-		}
-
-		if nodeID == nil {
-			nodeID = make([]byte, 6)
-			_, err := rand.Read(nodeID)
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	copy(uuid[10:], nodeID)
-
-	// set version(v1)
-	version.Set(uuid, version.TimeBased)
-	// set layout(RFC4122)
-	layout.Set(uuid, layout.RFC4122)
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go b/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go
deleted file mode 100644
index 2862711a022e9f06fa763ea6546700e7765f2aed..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/version/utility.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package version
-
-// Set sets the version for uuid.
-func Set(uuid []byte, version Version) {
-	switch version {
-	case TimeBased:
-		uuid[6] = (uuid[6] | 0x10) & 0x1f
-	case DCESecurity:
-		uuid[6] = (uuid[6] | 0x20) & 0x2f
-	case NameBasedMD5:
-		uuid[6] = (uuid[6] | 0x30) & 0x3f
-	case Random:
-		uuid[6] = (uuid[6] | 0x40) & 0x4f
-	case NameBasedSHA1:
-		uuid[6] = (uuid[6] | 0x50) & 0x5f
-	default:
-		panic("uuid: version is unknown")
-	}
-}
-
-// Get gets the version of uuid.
-func Get(uuid []byte) Version {
-	version := uuid[6] >> 4
-	if version > 0 && version < 6 {
-		return Version(version)
-	}
-
-	return Unknown
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go b/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go
deleted file mode 100644
index 10ab52cfa15cde59be546f2c21dc49e24b79103c..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/internal/version/version.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package version
-
-// Version represents the version of UUID. See page 7 in RFC 4122.
-type Version byte
-
-// Version List
-const (
-	Unknown       Version = iota // Unknwon
-	TimeBased                    // V1: The time-based version
-	DCESecurity                  // V2: The DCE security version, with embedded POSIX UIDs
-	NameBasedMD5                 // V3: The name-based version that uses MD5 hashing
-	Random                       // V4: The randomly or pseudo-randomly generated version
-	NameBasedSHA1                // V5: The name-based version that uses SHA-1 hashing
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/layout.go b/vendor/github.com/wayn3h0/go-uuid/layout.go
deleted file mode 100644
index 7656df5d163e6e15a85aeaef1d7ec9605d3885f0..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/layout.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package uuid
-
-import (
-	"github.com/wayn3h0/go-uuid/internal/layout"
-)
-
-// Layout represents the layout of UUID. See page 5 in RFC 4122.
-type Layout byte
-
-// Layouts.
-const (
-	LayoutInvalid   = Layout(layout.Invalid)   // Invalid
-	LayoutNCS       = Layout(layout.NCS)       // Reserved, NCS backward compatibility. (Values: 0x00-0x07)
-	LayoutRFC4122   = Layout(layout.RFC4122)   // The variant specified in RFC 4122. (Values: 0x08-0x0b)
-	LayoutMicrosoft = Layout(layout.Microsoft) // Reserved, Microsoft Corporation backward compatibility. (Values: 0x0c-0x0d)
-	LayoutFuture    = Layout(layout.Future)    // Reserved for future definition. (Values: 0x0e-0x0f)
-)
-
-// String returns English description of layout.
-func (this Layout) String() string {
-	switch this {
-	case LayoutNCS:
-		return "Layout: Reserved For NCS"
-	case LayoutRFC4122:
-		return "Layout: RFC 4122"
-	case LayoutMicrosoft:
-		return "Layout: Reserved For Microsoft"
-	case LayoutFuture:
-		return "Layout: Reserved For Future"
-	default:
-		return "Layout: Invalid"
-	}
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/namespace.go b/vendor/github.com/wayn3h0/go-uuid/namespace.go
deleted file mode 100644
index 23b314a56f84c63c6c9788a226d261d5b5545316..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/namespace.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package uuid
-
-import (
-	"github.com/wayn3h0/go-uuid/internal/namebased"
-)
-
-// Imports namespaces.
-const (
-	NamespaceDNS  = namebased.NamespaceDNS  // "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceURL  = namebased.NamespaceURL  // "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceOID  = namebased.NamespaceOID  // "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
-	NamespaceX500 = namebased.NamespaceX500 // "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
-)
diff --git a/vendor/github.com/wayn3h0/go-uuid/parse.go b/vendor/github.com/wayn3h0/go-uuid/parse.go
deleted file mode 100644
index 0847299c3cede87a69dea74f44860003d34b2722..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/parse.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package uuid
-
-import (
-	"encoding/hex"
-	"errors"
-	"fmt"
-)
-
-// Parse parses the UUID string.
-func Parse(str string) (UUID, error) {
-	length := len(str)
-	buffer := make([]byte, 16)
-	charIndexes := []int{}
-	switch length {
-	case 36:
-		if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' {
-			return Nil, fmt.Errorf("uuid: format of UUID string \"%s\" is invalid, it should be xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)", str)
-		}
-		charIndexes = []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34}
-	case 32:
-		charIndexes = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
-	default:
-		return Nil, fmt.Errorf("uuid: length of UUID string \"%s\" is invalid, it should be 36 (standard) or 32 (without dash)", str)
-	}
-	for i, v := range charIndexes {
-		if c, e := hex.DecodeString(str[v : v+2]); e != nil {
-			return Nil, fmt.Errorf("uuid: UUID string \"%s\" is invalid: %s", str, e.Error())
-		} else {
-			buffer[i] = c[0]
-		}
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], buffer)
-
-	if !uuid.Equal(Nil) {
-		if uuid.Layout() == LayoutInvalid {
-			return Nil, errors.New("uuid: layout is invalid")
-		}
-
-		if uuid.Version() == VersionUnknown {
-			return Nil, errors.New("uuid: version is unknown")
-		}
-	}
-
-	return uuid, nil
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/style.go b/vendor/github.com/wayn3h0/go-uuid/style.go
deleted file mode 100644
index 17b816a75c1d1b9ce8c7142b15a7fbbc527d6597..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/style.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package uuid
-
-// Style represents the style of UUID string.
-type Style byte
-
-// Styles.
-const (
-	StyleStandard    Style = iota + 1 // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12, length: 36)
-	StyleWithoutDash                  // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (length: 32)
-)
-
-// String returns English description of style.
-func (this Style) String() string {
-	switch this {
-	case StyleStandard:
-		return "Style: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)"
-	case StyleWithoutDash:
-		return "Style: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-	default:
-		return "Style: Unknown"
-	}
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/uuid.go b/vendor/github.com/wayn3h0/go-uuid/uuid.go
deleted file mode 100644
index ea17ec284621868df10e5b288a28ccb1b7a8476b..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/uuid.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package uuid
-
-import (
-	"bytes"
-	"fmt"
-
-	"github.com/wayn3h0/go-uuid/internal/dcesecurity"
-	"github.com/wayn3h0/go-uuid/internal/layout"
-	"github.com/wayn3h0/go-uuid/internal/namebased/md5"
-	"github.com/wayn3h0/go-uuid/internal/namebased/sha1"
-	"github.com/wayn3h0/go-uuid/internal/random"
-	"github.com/wayn3h0/go-uuid/internal/timebased"
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-var (
-	Nil = UUID{} // Nil UUID
-)
-
-// NewTimeBased returns a new time based UUID (version 1).
-func NewTimeBased() (UUID, error) {
-	u, err := timebased.New()
-	if err != nil {
-		return Nil, err
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], u)
-
-	return uuid, nil
-}
-
-// NewV1 same as NewTimeBased.
-func NewV1() (UUID, error) {
-	return NewTimeBased()
-}
-
-// NewDCESecurity returns a new DCE security UUID (version 2).
-func NewDCESecurity(domain Domain) (UUID, error) {
-	u, err := dcesecurity.New(dcesecurity.Domain(domain))
-	if err != nil {
-		return Nil, err
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], u)
-
-	return uuid, nil
-}
-
-// NewV2 same as NewDCESecurity.
-func NewV2(domain Domain) (UUID, error) {
-	return NewDCESecurity(domain)
-}
-
-// NewNameBasedMD5 returns a new name based UUID with MD5 hash (version 3).
-func NewNameBasedMD5(namespace, name string) (UUID, error) {
-	u, err := md5.New(namespace, name)
-	if err != nil {
-		return Nil, err
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], u)
-
-	return uuid, nil
-}
-
-// NewV3 same as NewNameBasedMD5.
-func NewV3(namespace, name string) (UUID, error) {
-	return NewNameBasedMD5(namespace, name)
-}
-
-// NewRandom returns a new random UUID (version 4).
-func NewRandom() (UUID, error) {
-	u, err := random.New()
-	if err != nil {
-		return Nil, err
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], u)
-
-	return uuid, nil
-}
-
-// NewV4 same as NewRandom.
-func NewV4() (UUID, error) {
-	return NewRandom()
-}
-
-// New same as NewRandom.
-func New() (UUID, error) {
-	return NewRandom()
-}
-
-// NewNameBasedSHA1 returns a new name based UUID with SHA1 hash (version 5).
-func NewNameBasedSHA1(namespace, name string) (UUID, error) {
-	u, err := sha1.New(namespace, name)
-	if err != nil {
-		return Nil, err
-	}
-
-	uuid := UUID{}
-	copy(uuid[:], u)
-
-	return uuid, nil
-}
-
-// NewV5 same as NewNameBasedSHA1.
-func NewV5(namespace, name string) (UUID, error) {
-	return NewNameBasedSHA1(namespace, name)
-}
-
-// UUID respresents an UUID type compliant with specification in RFC 4122.
-type UUID [16]byte
-
-// Layout returns layout of UUID.
-func (this UUID) Layout() Layout {
-	return Layout(layout.Get(this[:]))
-}
-
-// Version returns version of UUID.
-func (this UUID) Version() Version {
-	return Version(version.Get(this[:]))
-}
-
-// Equal returns true if current uuid equal to passed uuid.
-func (this UUID) Equal(another UUID) bool {
-	return bytes.EqualFold(this[:], another[:])
-}
-
-// Format returns the formatted string of UUID.
-func (this UUID) Format(style Style) string {
-	switch style {
-	case StyleWithoutDash:
-		return fmt.Sprintf("%x", this[:])
-	//case StyleStandard:
-	default:
-		return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", this[:4], this[4:6], this[6:8], this[8:10], this[10:])
-	}
-}
-
-// String returns the string of UUID with standard style(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | 8-4-4-4-12).
-func (this UUID) String() string {
-	return this.Format(StyleStandard)
-}
diff --git a/vendor/github.com/wayn3h0/go-uuid/version.go b/vendor/github.com/wayn3h0/go-uuid/version.go
deleted file mode 100644
index af509e3a3bb170dc45576c415d38f3c6f0444ffe..0000000000000000000000000000000000000000
--- a/vendor/github.com/wayn3h0/go-uuid/version.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package uuid
-
-import (
-	"github.com/wayn3h0/go-uuid/internal/version"
-)
-
-// Version represents the version of UUID. See page 7 in RFC 4122.
-type Version byte
-
-// Versions.
-const (
-	VersionUnknown       = Version(version.Unknown)       // Unknown
-	VersionTimeBased     = Version(version.TimeBased)     // V1: The time-based version
-	VersionDCESecurity   = Version(version.DCESecurity)   // V2: The DCE security version, with embedded POSIX UIDs
-	VersionNameBasedMD5  = Version(version.NameBasedMD5)  // V3: The name-based version that uses MD5 hashing
-	VersionRandom        = Version(version.Random)        // V4: The randomly or pseudo-randomly generated version
-	VersionNameBasedSHA1 = Version(version.NameBasedSHA1) // V5: The name-based version that uses SHA-1 hashing
-)
-
-// Short names.
-const (
-	V1 = VersionTimeBased
-	V2 = VersionDCESecurity
-	V3 = VersionNameBasedMD5
-	V4 = VersionRandom
-	V5 = VersionNameBasedSHA1
-)
-
-// String returns English description of version.
-func (this Version) String() string {
-	switch this {
-	case VersionTimeBased:
-		return "Version 1: Time-Based"
-	case VersionDCESecurity:
-		return "Version 2: DCE Security With Embedded POSIX UIDs"
-	case VersionNameBasedMD5:
-		return "Version 3: Name-Based (MD5)"
-	case VersionRandom:
-		return "Version 4: Randomly OR Pseudo-Randomly Generated"
-	case VersionNameBasedSHA1:
-		return "Version 5: Name-Based (SHA-1)"
-	default:
-		return "Version: Unknown"
-	}
-}
diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
new file mode 100644
index 0000000000000000000000000000000000000000..593f6530084f246495fc42f2ce6d59a2bccb4c17
--- /dev/null
+++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
@@ -0,0 +1,77 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC
+2898 / PKCS #5 v2.0.
+
+A key derivation function is useful when encrypting data based on a password
+or any other not-fully-random data. It uses a pseudorandom function to derive
+a secure encryption key based on the password.
+
+While v2.0 of the standard defines only one pseudorandom function to use,
+HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved
+Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
+choose, you can pass the `New` functions from the different SHA packages to
+pbkdf2.Key.
+*/
+package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
+
+import (
+	"crypto/hmac"
+	"hash"
+)
+
+// Key derives a key from the password, salt and iteration count, returning a
+// []byte of length keylen that can be used as cryptographic key. The key is
+// derived based on the method described as PBKDF2 with the HMAC variant using
+// the supplied hash function.
+//
+// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
+// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
+// doing:
+//
+// 	dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
+//
+// Remember to get a good random salt. At least 8 bytes is recommended by the
+// RFC.
+//
+// Using a higher iteration count will increase the cost of an exhaustive
+// search but will also make derivation proportionally slower.
+func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
+	prf := hmac.New(h, password)
+	hashLen := prf.Size()
+	numBlocks := (keyLen + hashLen - 1) / hashLen
+
+	var buf [4]byte
+	dk := make([]byte, 0, numBlocks*hashLen)
+	U := make([]byte, hashLen)
+	for block := 1; block <= numBlocks; block++ {
+		// N.B.: || means concatenation, ^ means XOR
+		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
+		// U_1 = PRF(password, salt || uint(i))
+		prf.Reset()
+		prf.Write(salt)
+		buf[0] = byte(block >> 24)
+		buf[1] = byte(block >> 16)
+		buf[2] = byte(block >> 8)
+		buf[3] = byte(block)
+		prf.Write(buf[:4])
+		dk = prf.Sum(dk)
+		T := dk[len(dk)-hashLen:]
+		copy(U, T)
+
+		// U_n = PRF(password, U_(n-1))
+		for n := 2; n <= iter; n++ {
+			prf.Reset()
+			prf.Write(U)
+			U = U[:0]
+			U = prf.Sum(U)
+			for x := range U {
+				T[x] ^= U[x]
+			}
+		}
+	}
+	return dk[:keyLen]
+}
diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go
new file mode 100644
index 0000000000000000000000000000000000000000..ff28aaef6ff2f091efe8cdbae93da4c402908bd1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go
@@ -0,0 +1,244 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package scrypt implements the scrypt key derivation function as defined in
+// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
+// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf).
+package scrypt // import "golang.org/x/crypto/scrypt"
+
+import (
+	"crypto/sha256"
+	"errors"
+
+	"golang.org/x/crypto/pbkdf2"
+)
+
+const maxInt = int(^uint(0) >> 1)
+
+// blockCopy copies n numbers from src into dst.
+func blockCopy(dst, src []uint32, n int) {
+	copy(dst, src[:n])
+}
+
+// blockXOR XORs numbers from dst with n numbers from src.
+func blockXOR(dst, src []uint32, n int) {
+	for i, v := range src[:n] {
+		dst[i] ^= v
+	}
+}
+
+// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in,
+// and puts the result into both both tmp and out.
+func salsaXOR(tmp *[16]uint32, in, out []uint32) {
+	w0 := tmp[0] ^ in[0]
+	w1 := tmp[1] ^ in[1]
+	w2 := tmp[2] ^ in[2]
+	w3 := tmp[3] ^ in[3]
+	w4 := tmp[4] ^ in[4]
+	w5 := tmp[5] ^ in[5]
+	w6 := tmp[6] ^ in[6]
+	w7 := tmp[7] ^ in[7]
+	w8 := tmp[8] ^ in[8]
+	w9 := tmp[9] ^ in[9]
+	w10 := tmp[10] ^ in[10]
+	w11 := tmp[11] ^ in[11]
+	w12 := tmp[12] ^ in[12]
+	w13 := tmp[13] ^ in[13]
+	w14 := tmp[14] ^ in[14]
+	w15 := tmp[15] ^ in[15]
+
+	x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
+	x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
+
+	for i := 0; i < 8; i += 2 {
+		u := x0 + x12
+		x4 ^= u<<7 | u>>(32-7)
+		u = x4 + x0
+		x8 ^= u<<9 | u>>(32-9)
+		u = x8 + x4
+		x12 ^= u<<13 | u>>(32-13)
+		u = x12 + x8
+		x0 ^= u<<18 | u>>(32-18)
+
+		u = x5 + x1
+		x9 ^= u<<7 | u>>(32-7)
+		u = x9 + x5
+		x13 ^= u<<9 | u>>(32-9)
+		u = x13 + x9
+		x1 ^= u<<13 | u>>(32-13)
+		u = x1 + x13
+		x5 ^= u<<18 | u>>(32-18)
+
+		u = x10 + x6
+		x14 ^= u<<7 | u>>(32-7)
+		u = x14 + x10
+		x2 ^= u<<9 | u>>(32-9)
+		u = x2 + x14
+		x6 ^= u<<13 | u>>(32-13)
+		u = x6 + x2
+		x10 ^= u<<18 | u>>(32-18)
+
+		u = x15 + x11
+		x3 ^= u<<7 | u>>(32-7)
+		u = x3 + x15
+		x7 ^= u<<9 | u>>(32-9)
+		u = x7 + x3
+		x11 ^= u<<13 | u>>(32-13)
+		u = x11 + x7
+		x15 ^= u<<18 | u>>(32-18)
+
+		u = x0 + x3
+		x1 ^= u<<7 | u>>(32-7)
+		u = x1 + x0
+		x2 ^= u<<9 | u>>(32-9)
+		u = x2 + x1
+		x3 ^= u<<13 | u>>(32-13)
+		u = x3 + x2
+		x0 ^= u<<18 | u>>(32-18)
+
+		u = x5 + x4
+		x6 ^= u<<7 | u>>(32-7)
+		u = x6 + x5
+		x7 ^= u<<9 | u>>(32-9)
+		u = x7 + x6
+		x4 ^= u<<13 | u>>(32-13)
+		u = x4 + x7
+		x5 ^= u<<18 | u>>(32-18)
+
+		u = x10 + x9
+		x11 ^= u<<7 | u>>(32-7)
+		u = x11 + x10
+		x8 ^= u<<9 | u>>(32-9)
+		u = x8 + x11
+		x9 ^= u<<13 | u>>(32-13)
+		u = x9 + x8
+		x10 ^= u<<18 | u>>(32-18)
+
+		u = x15 + x14
+		x12 ^= u<<7 | u>>(32-7)
+		u = x12 + x15
+		x13 ^= u<<9 | u>>(32-9)
+		u = x13 + x12
+		x14 ^= u<<13 | u>>(32-13)
+		u = x14 + x13
+		x15 ^= u<<18 | u>>(32-18)
+	}
+	x0 += w0
+	x1 += w1
+	x2 += w2
+	x3 += w3
+	x4 += w4
+	x5 += w5
+	x6 += w6
+	x7 += w7
+	x8 += w8
+	x9 += w9
+	x10 += w10
+	x11 += w11
+	x12 += w12
+	x13 += w13
+	x14 += w14
+	x15 += w15
+
+	out[0], tmp[0] = x0, x0
+	out[1], tmp[1] = x1, x1
+	out[2], tmp[2] = x2, x2
+	out[3], tmp[3] = x3, x3
+	out[4], tmp[4] = x4, x4
+	out[5], tmp[5] = x5, x5
+	out[6], tmp[6] = x6, x6
+	out[7], tmp[7] = x7, x7
+	out[8], tmp[8] = x8, x8
+	out[9], tmp[9] = x9, x9
+	out[10], tmp[10] = x10, x10
+	out[11], tmp[11] = x11, x11
+	out[12], tmp[12] = x12, x12
+	out[13], tmp[13] = x13, x13
+	out[14], tmp[14] = x14, x14
+	out[15], tmp[15] = x15, x15
+}
+
+func blockMix(tmp *[16]uint32, in, out []uint32, r int) {
+	blockCopy(tmp[:], in[(2*r-1)*16:], 16)
+	for i := 0; i < 2*r; i += 2 {
+		salsaXOR(tmp, in[i*16:], out[i*8:])
+		salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:])
+	}
+}
+
+func integer(b []uint32, r int) uint64 {
+	j := (2*r - 1) * 16
+	return uint64(b[j]) | uint64(b[j+1])<<32
+}
+
+func smix(b []byte, r, N int, v, xy []uint32) {
+	var tmp [16]uint32
+	x := xy
+	y := xy[32*r:]
+
+	j := 0
+	for i := 0; i < 32*r; i++ {
+		x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24
+		j += 4
+	}
+	for i := 0; i < N; i += 2 {
+		blockCopy(v[i*(32*r):], x, 32*r)
+		blockMix(&tmp, x, y, r)
+
+		blockCopy(v[(i+1)*(32*r):], y, 32*r)
+		blockMix(&tmp, y, x, r)
+	}
+	for i := 0; i < N; i += 2 {
+		j := int(integer(x, r) & uint64(N-1))
+		blockXOR(x, v[j*(32*r):], 32*r)
+		blockMix(&tmp, x, y, r)
+
+		j = int(integer(y, r) & uint64(N-1))
+		blockXOR(y, v[j*(32*r):], 32*r)
+		blockMix(&tmp, y, x, r)
+	}
+	j = 0
+	for _, v := range x[:32*r] {
+		b[j+0] = byte(v >> 0)
+		b[j+1] = byte(v >> 8)
+		b[j+2] = byte(v >> 16)
+		b[j+3] = byte(v >> 24)
+		j += 4
+	}
+}
+
+// Key derives a key from the password, salt, and cost parameters, returning
+// a byte slice of length keyLen that can be used as cryptographic key.
+//
+// N is a CPU/memory cost parameter, which must be a power of two greater than 1.
+// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
+// limits, the function returns a nil byte slice and an error.
+//
+// For example, you can get a derived key for e.g. AES-256 (which needs a
+// 32-byte key) by doing:
+//
+//      dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
+//
+// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
+// and p=1. The parameters N, r, and p should be increased as memory latency and
+// CPU parallelism increases; consider setting N to the highest power of 2 you
+// can derive within 100 milliseconds. Remember to get a good random salt.
+func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
+	if N <= 1 || N&(N-1) != 0 {
+		return nil, errors.New("scrypt: N must be > 1 and a power of 2")
+	}
+	if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
+		return nil, errors.New("scrypt: parameters are too large")
+	}
+
+	xy := make([]uint32, 64*r)
+	v := make([]uint32, 32*N*r)
+	b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)
+
+	for i := 0; i < p; i++ {
+		smix(b[i*128*r:], r, N, v, xy)
+	}
+
+	return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
new file mode 100644
index 0000000000000000000000000000000000000000..9a887598ff40437dae4a6a85dd8502e428917450
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
@@ -0,0 +1,951 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package terminal
+
+import (
+	"bytes"
+	"io"
+	"sync"
+	"unicode/utf8"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes struct {
+	// Foreground colors
+	Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
+
+	// Reset all attributes
+	Reset []byte
+}
+
+var vt100EscapeCodes = EscapeCodes{
+	Black:   []byte{keyEscape, '[', '3', '0', 'm'},
+	Red:     []byte{keyEscape, '[', '3', '1', 'm'},
+	Green:   []byte{keyEscape, '[', '3', '2', 'm'},
+	Yellow:  []byte{keyEscape, '[', '3', '3', 'm'},
+	Blue:    []byte{keyEscape, '[', '3', '4', 'm'},
+	Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
+	Cyan:    []byte{keyEscape, '[', '3', '6', 'm'},
+	White:   []byte{keyEscape, '[', '3', '7', 'm'},
+
+	Reset: []byte{keyEscape, '[', '0', 'm'},
+}
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal struct {
+	// AutoCompleteCallback, if non-null, is called for each keypress with
+	// the full input line and the current position of the cursor (in
+	// bytes, as an index into |line|). If it returns ok=false, the key
+	// press is processed normally. Otherwise it returns a replacement line
+	// and the new cursor position.
+	AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
+
+	// Escape contains a pointer to the escape codes for this terminal.
+	// It's always a valid pointer, although the escape codes themselves
+	// may be empty if the terminal doesn't support them.
+	Escape *EscapeCodes
+
+	// lock protects the terminal and the state in this object from
+	// concurrent processing of a key press and a Write() call.
+	lock sync.Mutex
+
+	c      io.ReadWriter
+	prompt []rune
+
+	// line is the current line being entered.
+	line []rune
+	// pos is the logical position of the cursor in line
+	pos int
+	// echo is true if local echo is enabled
+	echo bool
+	// pasteActive is true iff there is a bracketed paste operation in
+	// progress.
+	pasteActive bool
+
+	// cursorX contains the current X value of the cursor where the left
+	// edge is 0. cursorY contains the row number where the first row of
+	// the current line is 0.
+	cursorX, cursorY int
+	// maxLine is the greatest value of cursorY so far.
+	maxLine int
+
+	termWidth, termHeight int
+
+	// outBuf contains the terminal data to be sent.
+	outBuf []byte
+	// remainder contains the remainder of any partial key sequences after
+	// a read. It aliases into inBuf.
+	remainder []byte
+	inBuf     [256]byte
+
+	// history contains previously entered commands so that they can be
+	// accessed with the up and down keys.
+	history stRingBuffer
+	// historyIndex stores the currently accessed history entry, where zero
+	// means the immediately previous entry.
+	historyIndex int
+	// When navigating up and down the history it's possible to return to
+	// the incomplete, initial line. That value is stored in
+	// historyPending.
+	historyPending string
+}
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+	return &Terminal{
+		Escape:       &vt100EscapeCodes,
+		c:            c,
+		prompt:       []rune(prompt),
+		termWidth:    80,
+		termHeight:   24,
+		echo:         true,
+		historyIndex: -1,
+	}
+}
+
+const (
+	keyCtrlD     = 4
+	keyCtrlU     = 21
+	keyEnter     = '\r'
+	keyEscape    = 27
+	keyBackspace = 127
+	keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
+	keyUp
+	keyDown
+	keyLeft
+	keyRight
+	keyAltLeft
+	keyAltRight
+	keyHome
+	keyEnd
+	keyDeleteWord
+	keyDeleteLine
+	keyClearScreen
+	keyPasteStart
+	keyPasteEnd
+)
+
+var (
+	crlf       = []byte{'\r', '\n'}
+	pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
+	pasteEnd   = []byte{keyEscape, '[', '2', '0', '1', '~'}
+)
+
+// bytesToKey tries to parse a key sequence from b. If successful, it returns
+// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
+func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
+	if len(b) == 0 {
+		return utf8.RuneError, nil
+	}
+
+	if !pasteActive {
+		switch b[0] {
+		case 1: // ^A
+			return keyHome, b[1:]
+		case 5: // ^E
+			return keyEnd, b[1:]
+		case 8: // ^H
+			return keyBackspace, b[1:]
+		case 11: // ^K
+			return keyDeleteLine, b[1:]
+		case 12: // ^L
+			return keyClearScreen, b[1:]
+		case 23: // ^W
+			return keyDeleteWord, b[1:]
+		}
+	}
+
+	if b[0] != keyEscape {
+		if !utf8.FullRune(b) {
+			return utf8.RuneError, b
+		}
+		r, l := utf8.DecodeRune(b)
+		return r, b[l:]
+	}
+
+	if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
+		switch b[2] {
+		case 'A':
+			return keyUp, b[3:]
+		case 'B':
+			return keyDown, b[3:]
+		case 'C':
+			return keyRight, b[3:]
+		case 'D':
+			return keyLeft, b[3:]
+		case 'H':
+			return keyHome, b[3:]
+		case 'F':
+			return keyEnd, b[3:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
+		switch b[5] {
+		case 'C':
+			return keyAltRight, b[6:]
+		case 'D':
+			return keyAltLeft, b[6:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
+		return keyPasteStart, b[6:]
+	}
+
+	if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
+		return keyPasteEnd, b[6:]
+	}
+
+	// If we get here then we have a key that we don't recognise, or a
+	// partial sequence. It's not clear how one should find the end of a
+	// sequence without knowing them all, but it seems that [a-zA-Z~] only
+	// appears at the end of a sequence.
+	for i, c := range b[0:] {
+		if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
+			return keyUnknown, b[i+1:]
+		}
+	}
+
+	return utf8.RuneError, b
+}
+
+// queue appends data to the end of t.outBuf
+func (t *Terminal) queue(data []rune) {
+	t.outBuf = append(t.outBuf, []byte(string(data))...)
+}
+
+var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
+var space = []rune{' '}
+
+func isPrintable(key rune) bool {
+	isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
+	return key >= 32 && !isInSurrogateArea
+}
+
+// moveCursorToPos appends data to t.outBuf which will move the cursor to the
+// given, logical position in the text.
+func (t *Terminal) moveCursorToPos(pos int) {
+	if !t.echo {
+		return
+	}
+
+	x := visualLength(t.prompt) + pos
+	y := x / t.termWidth
+	x = x % t.termWidth
+
+	up := 0
+	if y < t.cursorY {
+		up = t.cursorY - y
+	}
+
+	down := 0
+	if y > t.cursorY {
+		down = y - t.cursorY
+	}
+
+	left := 0
+	if x < t.cursorX {
+		left = t.cursorX - x
+	}
+
+	right := 0
+	if x > t.cursorX {
+		right = x - t.cursorX
+	}
+
+	t.cursorX = x
+	t.cursorY = y
+	t.move(up, down, left, right)
+}
+
+func (t *Terminal) move(up, down, left, right int) {
+	movement := make([]rune, 3*(up+down+left+right))
+	m := movement
+	for i := 0; i < up; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'A'
+		m = m[3:]
+	}
+	for i := 0; i < down; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'B'
+		m = m[3:]
+	}
+	for i := 0; i < left; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'D'
+		m = m[3:]
+	}
+	for i := 0; i < right; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'C'
+		m = m[3:]
+	}
+
+	t.queue(movement)
+}
+
+func (t *Terminal) clearLineToRight() {
+	op := []rune{keyEscape, '[', 'K'}
+	t.queue(op)
+}
+
+const maxLineLength = 4096
+
+func (t *Terminal) setLine(newLine []rune, newPos int) {
+	if t.echo {
+		t.moveCursorToPos(0)
+		t.writeLine(newLine)
+		for i := len(newLine); i < len(t.line); i++ {
+			t.writeLine(space)
+		}
+		t.moveCursorToPos(newPos)
+	}
+	t.line = newLine
+	t.pos = newPos
+}
+
+func (t *Terminal) advanceCursor(places int) {
+	t.cursorX += places
+	t.cursorY += t.cursorX / t.termWidth
+	if t.cursorY > t.maxLine {
+		t.maxLine = t.cursorY
+	}
+	t.cursorX = t.cursorX % t.termWidth
+
+	if places > 0 && t.cursorX == 0 {
+		// Normally terminals will advance the current position
+		// when writing a character. But that doesn't happen
+		// for the last character in a line. However, when
+		// writing a character (except a new line) that causes
+		// a line wrap, the position will be advanced two
+		// places.
+		//
+		// So, if we are stopping at the end of a line, we
+		// need to write a newline so that our cursor can be
+		// advanced to the next line.
+		t.outBuf = append(t.outBuf, '\r', '\n')
+	}
+}
+
+func (t *Terminal) eraseNPreviousChars(n int) {
+	if n == 0 {
+		return
+	}
+
+	if t.pos < n {
+		n = t.pos
+	}
+	t.pos -= n
+	t.moveCursorToPos(t.pos)
+
+	copy(t.line[t.pos:], t.line[n+t.pos:])
+	t.line = t.line[:len(t.line)-n]
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+		for i := 0; i < n; i++ {
+			t.queue(space)
+		}
+		t.advanceCursor(n)
+		t.moveCursorToPos(t.pos)
+	}
+}
+
+// countToLeftWord returns then number of characters from the cursor to the
+// start of the previous word.
+func (t *Terminal) countToLeftWord() int {
+	if t.pos == 0 {
+		return 0
+	}
+
+	pos := t.pos - 1
+	for pos > 0 {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos--
+	}
+	for pos > 0 {
+		if t.line[pos] == ' ' {
+			pos++
+			break
+		}
+		pos--
+	}
+
+	return t.pos - pos
+}
+
+// countToRightWord returns then number of characters from the cursor to the
+// start of the next word.
+func (t *Terminal) countToRightWord() int {
+	pos := t.pos
+	for pos < len(t.line) {
+		if t.line[pos] == ' ' {
+			break
+		}
+		pos++
+	}
+	for pos < len(t.line) {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos++
+	}
+	return pos - t.pos
+}
+
+// visualLength returns the number of visible glyphs in s.
+func visualLength(runes []rune) int {
+	inEscapeSeq := false
+	length := 0
+
+	for _, r := range runes {
+		switch {
+		case inEscapeSeq:
+			if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
+				inEscapeSeq = false
+			}
+		case r == '\x1b':
+			inEscapeSeq = true
+		default:
+			length++
+		}
+	}
+
+	return length
+}
+
+// handleKey processes the given key and, optionally, returns a line of text
+// that the user has entered.
+func (t *Terminal) handleKey(key rune) (line string, ok bool) {
+	if t.pasteActive && key != keyEnter {
+		t.addKeyToLine(key)
+		return
+	}
+
+	switch key {
+	case keyBackspace:
+		if t.pos == 0 {
+			return
+		}
+		t.eraseNPreviousChars(1)
+	case keyAltLeft:
+		// move left by a word.
+		t.pos -= t.countToLeftWord()
+		t.moveCursorToPos(t.pos)
+	case keyAltRight:
+		// move right by a word.
+		t.pos += t.countToRightWord()
+		t.moveCursorToPos(t.pos)
+	case keyLeft:
+		if t.pos == 0 {
+			return
+		}
+		t.pos--
+		t.moveCursorToPos(t.pos)
+	case keyRight:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos++
+		t.moveCursorToPos(t.pos)
+	case keyHome:
+		if t.pos == 0 {
+			return
+		}
+		t.pos = 0
+		t.moveCursorToPos(t.pos)
+	case keyEnd:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos = len(t.line)
+		t.moveCursorToPos(t.pos)
+	case keyUp:
+		entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
+		if !ok {
+			return "", false
+		}
+		if t.historyIndex == -1 {
+			t.historyPending = string(t.line)
+		}
+		t.historyIndex++
+		runes := []rune(entry)
+		t.setLine(runes, len(runes))
+	case keyDown:
+		switch t.historyIndex {
+		case -1:
+			return
+		case 0:
+			runes := []rune(t.historyPending)
+			t.setLine(runes, len(runes))
+			t.historyIndex--
+		default:
+			entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
+			if ok {
+				t.historyIndex--
+				runes := []rune(entry)
+				t.setLine(runes, len(runes))
+			}
+		}
+	case keyEnter:
+		t.moveCursorToPos(len(t.line))
+		t.queue([]rune("\r\n"))
+		line = string(t.line)
+		ok = true
+		t.line = t.line[:0]
+		t.pos = 0
+		t.cursorX = 0
+		t.cursorY = 0
+		t.maxLine = 0
+	case keyDeleteWord:
+		// Delete zero or more spaces and then one or more characters.
+		t.eraseNPreviousChars(t.countToLeftWord())
+	case keyDeleteLine:
+		// Delete everything from the current cursor position to the
+		// end of line.
+		for i := t.pos; i < len(t.line); i++ {
+			t.queue(space)
+			t.advanceCursor(1)
+		}
+		t.line = t.line[:t.pos]
+		t.moveCursorToPos(t.pos)
+	case keyCtrlD:
+		// Erase the character under the current position.
+		// The EOF case when the line is empty is handled in
+		// readLine().
+		if t.pos < len(t.line) {
+			t.pos++
+			t.eraseNPreviousChars(1)
+		}
+	case keyCtrlU:
+		t.eraseNPreviousChars(t.pos)
+	case keyClearScreen:
+		// Erases the screen and moves the cursor to the home position.
+		t.queue([]rune("\x1b[2J\x1b[H"))
+		t.queue(t.prompt)
+		t.cursorX, t.cursorY = 0, 0
+		t.advanceCursor(visualLength(t.prompt))
+		t.setLine(t.line, t.pos)
+	default:
+		if t.AutoCompleteCallback != nil {
+			prefix := string(t.line[:t.pos])
+			suffix := string(t.line[t.pos:])
+
+			t.lock.Unlock()
+			newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
+			t.lock.Lock()
+
+			if completeOk {
+				t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
+				return
+			}
+		}
+		if !isPrintable(key) {
+			return
+		}
+		if len(t.line) == maxLineLength {
+			return
+		}
+		t.addKeyToLine(key)
+	}
+	return
+}
+
+// addKeyToLine inserts the given key at the current position in the current
+// line.
+func (t *Terminal) addKeyToLine(key rune) {
+	if len(t.line) == cap(t.line) {
+		newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
+		copy(newLine, t.line)
+		t.line = newLine
+	}
+	t.line = t.line[:len(t.line)+1]
+	copy(t.line[t.pos+1:], t.line[t.pos:])
+	t.line[t.pos] = key
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+	}
+	t.pos++
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) writeLine(line []rune) {
+	for len(line) != 0 {
+		remainingOnLine := t.termWidth - t.cursorX
+		todo := len(line)
+		if todo > remainingOnLine {
+			todo = remainingOnLine
+		}
+		t.queue(line[:todo])
+		t.advanceCursor(visualLength(line[:todo]))
+		line = line[todo:]
+	}
+}
+
+// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
+func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
+	for len(buf) > 0 {
+		i := bytes.IndexByte(buf, '\n')
+		todo := len(buf)
+		if i >= 0 {
+			todo = i
+		}
+
+		var nn int
+		nn, err = w.Write(buf[:todo])
+		n += nn
+		if err != nil {
+			return n, err
+		}
+		buf = buf[todo:]
+
+		if i >= 0 {
+			if _, err = w.Write(crlf); err != nil {
+				return n, err
+			}
+			n++
+			buf = buf[1:]
+		}
+	}
+
+	return n, nil
+}
+
+func (t *Terminal) Write(buf []byte) (n int, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		// This is the easy case: there's nothing on the screen that we
+		// have to move out of the way.
+		return writeWithCRLF(t.c, buf)
+	}
+
+	// We have a prompt and possibly user input on the screen. We
+	// have to clear it first.
+	t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
+	t.cursorX = 0
+	t.clearLineToRight()
+
+	for t.cursorY > 0 {
+		t.move(1 /* up */, 0, 0, 0)
+		t.cursorY--
+		t.clearLineToRight()
+	}
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+
+	if n, err = writeWithCRLF(t.c, buf); err != nil {
+		return
+	}
+
+	t.writeLine(t.prompt)
+	if t.echo {
+		t.writeLine(t.line)
+	}
+
+	t.moveCursorToPos(t.pos)
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+	return
+}
+
+// ReadPassword temporarily changes the prompt and reads a password, without
+// echo, from the terminal.
+func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	oldPrompt := t.prompt
+	t.prompt = []rune(prompt)
+	t.echo = false
+
+	line, err = t.readLine()
+
+	t.prompt = oldPrompt
+	t.echo = true
+
+	return
+}
+
+// ReadLine returns a line of input from the terminal.
+func (t *Terminal) ReadLine() (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	return t.readLine()
+}
+
+func (t *Terminal) readLine() (line string, err error) {
+	// t.lock must be held at this point
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		t.writeLine(t.prompt)
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+	}
+
+	lineIsPasted := t.pasteActive
+
+	for {
+		rest := t.remainder
+		lineOk := false
+		for !lineOk {
+			var key rune
+			key, rest = bytesToKey(rest, t.pasteActive)
+			if key == utf8.RuneError {
+				break
+			}
+			if !t.pasteActive {
+				if key == keyCtrlD {
+					if len(t.line) == 0 {
+						return "", io.EOF
+					}
+				}
+				if key == keyPasteStart {
+					t.pasteActive = true
+					if len(t.line) == 0 {
+						lineIsPasted = true
+					}
+					continue
+				}
+			} else if key == keyPasteEnd {
+				t.pasteActive = false
+				continue
+			}
+			if !t.pasteActive {
+				lineIsPasted = false
+			}
+			line, lineOk = t.handleKey(key)
+		}
+		if len(rest) > 0 {
+			n := copy(t.inBuf[:], rest)
+			t.remainder = t.inBuf[:n]
+		} else {
+			t.remainder = nil
+		}
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+		if lineOk {
+			if t.echo {
+				t.historyIndex = -1
+				t.history.Add(line)
+			}
+			if lineIsPasted {
+				err = ErrPasteIndicator
+			}
+			return
+		}
+
+		// t.remainder is a slice at the beginning of t.inBuf
+		// containing a partial key sequence
+		readBuf := t.inBuf[len(t.remainder):]
+		var n int
+
+		t.lock.Unlock()
+		n, err = t.c.Read(readBuf)
+		t.lock.Lock()
+
+		if err != nil {
+			return
+		}
+
+		t.remainder = t.inBuf[:n+len(t.remainder)]
+	}
+}
+
+// SetPrompt sets the prompt to be used when reading subsequent lines.
+func (t *Terminal) SetPrompt(prompt string) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	t.prompt = []rune(prompt)
+}
+
+func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
+	// Move cursor to column zero at the start of the line.
+	t.move(t.cursorY, 0, t.cursorX, 0)
+	t.cursorX, t.cursorY = 0, 0
+	t.clearLineToRight()
+	for t.cursorY < numPrevLines {
+		// Move down a line
+		t.move(0, 1, 0, 0)
+		t.cursorY++
+		t.clearLineToRight()
+	}
+	// Move back to beginning.
+	t.move(t.cursorY, 0, 0, 0)
+	t.cursorX, t.cursorY = 0, 0
+
+	t.queue(t.prompt)
+	t.advanceCursor(visualLength(t.prompt))
+	t.writeLine(t.line)
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) SetSize(width, height int) error {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if width == 0 {
+		width = 1
+	}
+
+	oldWidth := t.termWidth
+	t.termWidth, t.termHeight = width, height
+
+	switch {
+	case width == oldWidth:
+		// If the width didn't change then nothing else needs to be
+		// done.
+		return nil
+	case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
+		// If there is nothing on current line and no prompt printed,
+		// just do nothing
+		return nil
+	case width < oldWidth:
+		// Some terminals (e.g. xterm) will truncate lines that were
+		// too long when shinking. Others, (e.g. gnome-terminal) will
+		// attempt to wrap them. For the former, repainting t.maxLine
+		// works great, but that behaviour goes badly wrong in the case
+		// of the latter because they have doubled every full line.
+
+		// We assume that we are working on a terminal that wraps lines
+		// and adjust the cursor position based on every previous line
+		// wrapping and turning into two. This causes the prompt on
+		// xterms to move upwards, which isn't great, but it avoids a
+		// huge mess with gnome-terminal.
+		if t.cursorX >= t.termWidth {
+			t.cursorX = t.termWidth - 1
+		}
+		t.cursorY *= 2
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
+	case width > oldWidth:
+		// If the terminal expands then our position calculations will
+		// be wrong in the future because we think the cursor is
+		// |t.pos| chars into the string, but there will be a gap at
+		// the end of any wrapped line.
+		//
+		// But the position will actually be correct until we move, so
+		// we can move back to the beginning and repaint everything.
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine)
+	}
+
+	_, err := t.c.Write(t.outBuf)
+	t.outBuf = t.outBuf[:0]
+	return err
+}
+
+type pasteIndicatorError struct{}
+
+func (pasteIndicatorError) Error() string {
+	return "terminal: ErrPasteIndicator not correctly handled"
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = pasteIndicatorError{}
+
+// SetBracketedPasteMode requests that the terminal bracket paste operations
+// with markers. Not all terminals support this but, if it is supported, then
+// enabling this mode will stop any autocomplete callback from running due to
+// pastes. Additionally, any lines that are completely pasted will be returned
+// from ReadLine with the error set to ErrPasteIndicator.
+func (t *Terminal) SetBracketedPasteMode(on bool) {
+	if on {
+		io.WriteString(t.c, "\x1b[?2004h")
+	} else {
+		io.WriteString(t.c, "\x1b[?2004l")
+	}
+}
+
+// stRingBuffer is a ring buffer of strings.
+type stRingBuffer struct {
+	// entries contains max elements.
+	entries []string
+	max     int
+	// head contains the index of the element most recently added to the ring.
+	head int
+	// size contains the number of elements in the ring.
+	size int
+}
+
+func (s *stRingBuffer) Add(a string) {
+	if s.entries == nil {
+		const defaultNumEntries = 100
+		s.entries = make([]string, defaultNumEntries)
+		s.max = defaultNumEntries
+	}
+
+	s.head = (s.head + 1) % s.max
+	s.entries[s.head] = a
+	if s.size < s.max {
+		s.size++
+	}
+}
+
+// NthPreviousEntry returns the value passed to the nth previous call to Add.
+// If n is zero then the immediately prior value is returned, if one, then the
+// next most recent, and so on. If such an element doesn't exist then ok is
+// false.
+func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
+	if n >= s.size {
+		return "", false
+	}
+	index := s.head - n
+	if index < 0 {
+		index += s.max
+	}
+	return s.entries[index], true
+}
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+	var buf [1]byte
+	var ret []byte
+
+	for {
+		n, err := reader.Read(buf[:])
+		if n > 0 {
+			switch buf[0] {
+			case '\n':
+				return ret, nil
+			case '\r':
+				// remove \r from passwords on Windows
+			default:
+				ret = append(ret, buf[0])
+			}
+			continue
+		}
+		if err != nil {
+			if err == io.EOF && len(ret) > 0 {
+				return ret, nil
+			}
+			return ret, err
+		}
+	}
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go
new file mode 100644
index 0000000000000000000000000000000000000000..731c89a284a29f479297461539b17535ab5321d6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go
@@ -0,0 +1,114 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal // import "golang.org/x/crypto/ssh/terminal"
+
+import (
+	"golang.org/x/sys/unix"
+)
+
+// State contains the state of a terminal.
+type State struct {
+	termios unix.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	return err == nil
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	oldState := State{termios: *termios}
+
+	// This attempts to replicate the behaviour documented for cfmakeraw in
+	// the termios(3) manpage.
+	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+	termios.Oflag &^= unix.OPOST
+	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+	termios.Cflag &^= unix.CSIZE | unix.PARENB
+	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
+		return nil, err
+	}
+
+	return &oldState, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	return &State{termios: *termios}, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+	if err != nil {
+		return -1, -1, err
+	}
+	return int(ws.Col), int(ws.Row), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+	return unix.Read(int(r), buf)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
+		return nil, err
+	}
+
+	newState := *termios
+	newState.Lflag &^= unix.ECHO
+	newState.Lflag |= unix.ICANON | unix.ISIG
+	newState.Iflag |= unix.ICRNL
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
+		return nil, err
+	}
+
+	defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
+
+	return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
new file mode 100644
index 0000000000000000000000000000000000000000..cb23a590494015a5689166d40852762b777dd994
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
@@ -0,0 +1,12 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package terminal
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
+const ioctlWriteTermios = unix.TIOCSETA
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fadfe8a1d50ba10d6d4fea349fe5c7a983eb5da
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
@@ -0,0 +1,10 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package terminal
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+const ioctlWriteTermios = unix.TCSETS
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
new file mode 100644
index 0000000000000000000000000000000000000000..799f049f04ea0ce665e44e018780921e2bed0d02
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
@@ -0,0 +1,58 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+	"fmt"
+	"runtime"
+)
+
+type State struct{}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	return false
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
new file mode 100644
index 0000000000000000000000000000000000000000..9e41b9f43f089fbefb87121d19378deef35558a3
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
@@ -0,0 +1,124 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build solaris
+
+package terminal // import "golang.org/x/crypto/ssh/terminal"
+
+import (
+	"golang.org/x/sys/unix"
+	"io"
+	"syscall"
+)
+
+// State contains the state of a terminal.
+type State struct {
+	termios unix.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
+	return err == nil
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
+	val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+	oldState := *val
+
+	newState := oldState
+	newState.Lflag &^= syscall.ECHO
+	newState.Lflag |= syscall.ICANON | syscall.ISIG
+	newState.Iflag |= syscall.ICRNL
+	err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
+	if err != nil {
+		return nil, err
+	}
+
+	defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
+
+	var buf [16]byte
+	var ret []byte
+	for {
+		n, err := syscall.Read(fd, buf[:])
+		if err != nil {
+			return nil, err
+		}
+		if n == 0 {
+			if len(ret) == 0 {
+				return nil, io.EOF
+			}
+			break
+		}
+		if buf[n-1] == '\n' {
+			n--
+		}
+		ret = append(ret, buf[:n]...)
+		if n < len(buf) {
+			break
+		}
+	}
+
+	return ret, nil
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+// see http://cr.illumos.org/~webrev/andy_js/1060/
+func MakeRaw(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+
+	oldState := State{termios: *termios}
+
+	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+	termios.Oflag &^= unix.OPOST
+	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+	termios.Cflag &^= unix.CSIZE | unix.PARENB
+	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
+
+	if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil {
+		return nil, err
+	}
+
+	return &oldState, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+	return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+
+	return &State{termios: *termios}, nil
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+	if err != nil {
+		return 0, 0, err
+	}
+	return int(ws.Col), int(ws.Row), nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..8618955df7383cc1c33135befc356599a3be0199
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
@@ -0,0 +1,103 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+	"os"
+
+	"golang.org/x/sys/windows"
+)
+
+type State struct {
+	mode uint32
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	var st uint32
+	err := windows.GetConsoleMode(windows.Handle(fd), &st)
+	return err == nil
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+	if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
+		return nil, err
+	}
+	return &State{st}, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	return &State{st}, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	return windows.SetConsoleMode(windows.Handle(fd), state.mode)
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	var info windows.ConsoleScreenBufferInfo
+	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+		return 0, 0, err
+	}
+	return int(info.Size.X), int(info.Size.Y), nil
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	var st uint32
+	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
+		return nil, err
+	}
+	old := st
+
+	st &^= (windows.ENABLE_ECHO_INPUT)
+	st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
+	if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
+		return nil, err
+	}
+
+	defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+	var h windows.Handle
+	p, _ := windows.GetCurrentProcess()
+	if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+		return nil, err
+	}
+
+	f := os.NewFile(uintptr(h), "stdin")
+	defer f.Close()
+	return readPasswordLine(f)
+}
diff --git a/vendor/golang.org/x/sys/windows/asm_windows_386.s b/vendor/golang.org/x/sys/windows/asm_windows_386.s
new file mode 100644
index 0000000000000000000000000000000000000000..1c20dd2f897d021e9033f9a2d2da6bd9d1a97dca
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/asm_windows_386.s
@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls for 386, Windows are implemented in runtime/syscall_windows.goc
+//
+
+TEXT ·getprocaddress(SB), 7, $0-8
+	JMP	syscall·getprocaddress(SB)
+
+TEXT ·loadlibrary(SB), 7, $0-4
+	JMP	syscall·loadlibrary(SB)
diff --git a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s
new file mode 100644
index 0000000000000000000000000000000000000000..4d025ab556dbe2c3f7e11924023fd0b3a8b35676
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s
@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc
+//
+
+TEXT ·getprocaddress(SB), 7, $0-32
+	JMP	syscall·getprocaddress(SB)
+
+TEXT ·loadlibrary(SB), 7, $0-8
+	JMP	syscall·loadlibrary(SB)
diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..e92c05b213c8f63d960bd9c1ceedb20bb798e15b
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/dll_windows.go
@@ -0,0 +1,378 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import (
+	"sync"
+	"sync/atomic"
+	"syscall"
+	"unsafe"
+)
+
+// DLLError describes reasons for DLL load failures.
+type DLLError struct {
+	Err     error
+	ObjName string
+	Msg     string
+}
+
+func (e *DLLError) Error() string { return e.Msg }
+
+// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file.
+func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno)
+func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno)
+
+// A DLL implements access to a single DLL.
+type DLL struct {
+	Name   string
+	Handle Handle
+}
+
+// LoadDLL loads DLL file into memory.
+//
+// Warning: using LoadDLL without an absolute path name is subject to
+// DLL preloading attacks. To safely load a system DLL, use LazyDLL
+// with System set to true, or use LoadLibraryEx directly.
+func LoadDLL(name string) (dll *DLL, err error) {
+	namep, err := UTF16PtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	h, e := loadlibrary(namep)
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to load " + name + ": " + e.Error(),
+		}
+	}
+	d := &DLL{
+		Name:   name,
+		Handle: Handle(h),
+	}
+	return d, nil
+}
+
+// MustLoadDLL is like LoadDLL but panics if load operation failes.
+func MustLoadDLL(name string) *DLL {
+	d, e := LoadDLL(name)
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// FindProc searches DLL d for procedure named name and returns *Proc
+// if found. It returns an error if search fails.
+func (d *DLL) FindProc(name string) (proc *Proc, err error) {
+	namep, err := BytePtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	a, e := getprocaddress(uintptr(d.Handle), namep)
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
+		}
+	}
+	p := &Proc{
+		Dll:  d,
+		Name: name,
+		addr: a,
+	}
+	return p, nil
+}
+
+// MustFindProc is like FindProc but panics if search fails.
+func (d *DLL) MustFindProc(name string) *Proc {
+	p, e := d.FindProc(name)
+	if e != nil {
+		panic(e)
+	}
+	return p
+}
+
+// Release unloads DLL d from memory.
+func (d *DLL) Release() (err error) {
+	return FreeLibrary(d.Handle)
+}
+
+// A Proc implements access to a procedure inside a DLL.
+type Proc struct {
+	Dll  *DLL
+	Name string
+	addr uintptr
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *Proc) Addr() uintptr {
+	return p.addr
+}
+
+//go:uintptrescapes
+
+// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
+// are supplied.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain windows.Errno.
+func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	switch len(a) {
+	case 0:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
+	case 1:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
+	case 2:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
+	case 3:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
+	case 4:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
+	case 5:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
+	case 6:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
+	case 7:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
+	case 8:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
+	case 9:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
+	case 10:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
+	case 11:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
+	case 12:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
+	case 13:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
+	case 14:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
+	case 15:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
+	default:
+		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
+	}
+}
+
+// A LazyDLL implements access to a single DLL.
+// It will delay the load of the DLL until the first
+// call to its Handle method or to one of its
+// LazyProc's Addr method.
+type LazyDLL struct {
+	Name string
+
+	// System determines whether the DLL must be loaded from the
+	// Windows System directory, bypassing the normal DLL search
+	// path.
+	System bool
+
+	mu  sync.Mutex
+	dll *DLL // non nil once DLL is loaded
+}
+
+// Load loads DLL file d.Name into memory. It returns an error if fails.
+// Load will not try to load DLL, if it is already loaded into memory.
+func (d *LazyDLL) Load() error {
+	// Non-racy version of:
+	// if d.dll != nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil {
+		return nil
+	}
+	d.mu.Lock()
+	defer d.mu.Unlock()
+	if d.dll != nil {
+		return nil
+	}
+
+	// kernel32.dll is special, since it's where LoadLibraryEx comes from.
+	// The kernel already special-cases its name, so it's always
+	// loaded from system32.
+	var dll *DLL
+	var err error
+	if d.Name == "kernel32.dll" {
+		dll, err = LoadDLL(d.Name)
+	} else {
+		dll, err = loadLibraryEx(d.Name, d.System)
+	}
+	if err != nil {
+		return err
+	}
+
+	// Non-racy version of:
+	// d.dll = dll
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
+	return nil
+}
+
+// mustLoad is like Load but panics if search fails.
+func (d *LazyDLL) mustLoad() {
+	e := d.Load()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Handle returns d's module handle.
+func (d *LazyDLL) Handle() uintptr {
+	d.mustLoad()
+	return uintptr(d.dll.Handle)
+}
+
+// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
+func (d *LazyDLL) NewProc(name string) *LazyProc {
+	return &LazyProc{l: d, Name: name}
+}
+
+// NewLazyDLL creates new LazyDLL associated with DLL file.
+func NewLazyDLL(name string) *LazyDLL {
+	return &LazyDLL{Name: name}
+}
+
+// NewLazySystemDLL is like NewLazyDLL, but will only
+// search Windows System directory for the DLL if name is
+// a base name (like "advapi32.dll").
+func NewLazySystemDLL(name string) *LazyDLL {
+	return &LazyDLL{Name: name, System: true}
+}
+
+// A LazyProc implements access to a procedure inside a LazyDLL.
+// It delays the lookup until the Addr method is called.
+type LazyProc struct {
+	Name string
+
+	mu   sync.Mutex
+	l    *LazyDLL
+	proc *Proc
+}
+
+// Find searches DLL for procedure named p.Name. It returns
+// an error if search fails. Find will not search procedure,
+// if it is already found and loaded into memory.
+func (p *LazyProc) Find() error {
+	// Non-racy version of:
+	// if p.proc == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
+		p.mu.Lock()
+		defer p.mu.Unlock()
+		if p.proc == nil {
+			e := p.l.Load()
+			if e != nil {
+				return e
+			}
+			proc, e := p.l.dll.FindProc(p.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// p.proc = proc
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
+		}
+	}
+	return nil
+}
+
+// mustFind is like Find but panics if search fails.
+func (p *LazyProc) mustFind() {
+	e := p.Find()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+// It will panic if the procedure cannot be found.
+func (p *LazyProc) Addr() uintptr {
+	p.mustFind()
+	return p.proc.Addr()
+}
+
+//go:uintptrescapes
+
+// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
+// are supplied. It will also panic if the procedure cannot be found.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain windows.Errno.
+func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	p.mustFind()
+	return p.proc.Call(a...)
+}
+
+var canDoSearchSystem32Once struct {
+	sync.Once
+	v bool
+}
+
+func initCanDoSearchSystem32() {
+	// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
+	// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
+	// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
+	// systems that have KB2533623 installed. To determine whether the
+	// flags are available, use GetProcAddress to get the address of the
+	// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
+	// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
+	// flags can be used with LoadLibraryEx."
+	canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil)
+}
+
+func canDoSearchSystem32() bool {
+	canDoSearchSystem32Once.Do(initCanDoSearchSystem32)
+	return canDoSearchSystem32Once.v
+}
+
+func isBaseName(name string) bool {
+	for _, c := range name {
+		if c == ':' || c == '/' || c == '\\' {
+			return false
+		}
+	}
+	return true
+}
+
+// loadLibraryEx wraps the Windows LoadLibraryEx function.
+//
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
+//
+// If name is not an absolute path, LoadLibraryEx searches for the DLL
+// in a variety of automatic locations unless constrained by flags.
+// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx
+func loadLibraryEx(name string, system bool) (*DLL, error) {
+	loadDLL := name
+	var flags uintptr
+	if system {
+		if canDoSearchSystem32() {
+			const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
+			flags = LOAD_LIBRARY_SEARCH_SYSTEM32
+		} else if isBaseName(name) {
+			// WindowsXP or unpatched Windows machine
+			// trying to load "foo.dll" out of the system
+			// folder, but LoadLibraryEx doesn't support
+			// that yet on their system, so emulate it.
+			windir, _ := Getenv("WINDIR") // old var; apparently works on XP
+			if windir == "" {
+				return nil, errString("%WINDIR% not defined")
+			}
+			loadDLL = windir + "\\System32\\" + name
+		}
+	}
+	h, err := LoadLibraryEx(loadDLL, 0, flags)
+	if err != nil {
+		return nil, err
+	}
+	return &DLL{Name: name, Handle: h}, nil
+}
+
+type errString string
+
+func (s errString) Error() string { return string(s) }
diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..bdc71e241e0c6ee53c568a47377e9ea619393775
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/env_windows.go
@@ -0,0 +1,29 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows environment variables.
+
+package windows
+
+import "syscall"
+
+func Getenv(key string) (value string, found bool) {
+	return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+	return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+	syscall.Clearenv()
+}
+
+func Environ() []string {
+	return syscall.Environ()
+}
+
+func Unsetenv(key string) error {
+	return syscall.Unsetenv(key)
+}
diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go
new file mode 100644
index 0000000000000000000000000000000000000000..40af946e162f94306b65d77df160cdcd2b32ed72
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/eventlog.go
@@ -0,0 +1,20 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+const (
+	EVENTLOG_SUCCESS          = 0
+	EVENTLOG_ERROR_TYPE       = 1
+	EVENTLOG_WARNING_TYPE     = 2
+	EVENTLOG_INFORMATION_TYPE = 4
+	EVENTLOG_AUDIT_SUCCESS    = 8
+	EVENTLOG_AUDIT_FAILURE    = 16
+)
+
+//sys	RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW
+//sys	DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource
+//sys	ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW
diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..3606c3a8b3690599c77bb0460f40dd9327786c05
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/exec_windows.go
@@ -0,0 +1,97 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fork, exec, wait, etc.
+
+package windows
+
+// EscapeArg rewrites command line argument s as prescribed
+// in http://msdn.microsoft.com/en-us/library/ms880421.
+// This function returns "" (2 double quotes) if s is empty.
+// Alternatively, these transformations are done:
+// - every back slash (\) is doubled, but only if immediately
+//   followed by double quote (");
+// - every double quote (") is escaped by back slash (\);
+// - finally, s is wrapped with double quotes (arg -> "arg"),
+//   but only if there is space or tab inside s.
+func EscapeArg(s string) string {
+	if len(s) == 0 {
+		return "\"\""
+	}
+	n := len(s)
+	hasSpace := false
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '"', '\\':
+			n++
+		case ' ', '\t':
+			hasSpace = true
+		}
+	}
+	if hasSpace {
+		n += 2
+	}
+	if n == len(s) {
+		return s
+	}
+
+	qs := make([]byte, n)
+	j := 0
+	if hasSpace {
+		qs[j] = '"'
+		j++
+	}
+	slashes := 0
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		default:
+			slashes = 0
+			qs[j] = s[i]
+		case '\\':
+			slashes++
+			qs[j] = s[i]
+		case '"':
+			for ; slashes > 0; slashes-- {
+				qs[j] = '\\'
+				j++
+			}
+			qs[j] = '\\'
+			j++
+			qs[j] = s[i]
+		}
+		j++
+	}
+	if hasSpace {
+		for ; slashes > 0; slashes-- {
+			qs[j] = '\\'
+			j++
+		}
+		qs[j] = '"'
+		j++
+	}
+	return string(qs[:j])
+}
+
+func CloseOnExec(fd Handle) {
+	SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
+}
+
+// FullPath retrieves the full path of the specified file.
+func FullPath(name string) (path string, err error) {
+	p, err := UTF16PtrFromString(name)
+	if err != nil {
+		return "", err
+	}
+	n := uint32(100)
+	for {
+		buf := make([]uint16, n)
+		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
+		if err != nil {
+			return "", err
+		}
+		if n <= uint32(len(buf)) {
+			return UTF16ToString(buf[:n]), nil
+		}
+	}
+}
diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..f80a4204f097d884b94ccb2324b8694863d6877f
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/memory_windows.go
@@ -0,0 +1,26 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+const (
+	MEM_COMMIT      = 0x00001000
+	MEM_RESERVE     = 0x00002000
+	MEM_DECOMMIT    = 0x00004000
+	MEM_RELEASE     = 0x00008000
+	MEM_RESET       = 0x00080000
+	MEM_TOP_DOWN    = 0x00100000
+	MEM_WRITE_WATCH = 0x00200000
+	MEM_PHYSICAL    = 0x00400000
+	MEM_RESET_UNDO  = 0x01000000
+	MEM_LARGE_PAGES = 0x20000000
+
+	PAGE_NOACCESS          = 0x01
+	PAGE_READONLY          = 0x02
+	PAGE_READWRITE         = 0x04
+	PAGE_WRITECOPY         = 0x08
+	PAGE_EXECUTE_READ      = 0x20
+	PAGE_EXECUTE_READWRITE = 0x40
+	PAGE_EXECUTE_WRITECOPY = 0x80
+)
diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go
new file mode 100644
index 0000000000000000000000000000000000000000..fb7db0ef8d4af652fe6b62df59fb8808a32b4fae
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/mksyscall.go
@@ -0,0 +1,7 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go
diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go
new file mode 100644
index 0000000000000000000000000000000000000000..a74e3e24b557e9d99cb6643e0a274e14ba7654ba
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/race.go
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,race
+
+package windows
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+const raceenabled = true
+
+func raceAcquire(addr unsafe.Pointer) {
+	runtime.RaceAcquire(addr)
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+	runtime.RaceReleaseMerge(addr)
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+	runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+	runtime.RaceWriteRange(addr, len)
+}
diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go
new file mode 100644
index 0000000000000000000000000000000000000000..e44a3cbf67994455be845fcb87fde02f01787c55
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/race0.go
@@ -0,0 +1,25 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,!race
+
+package windows
+
+import (
+	"unsafe"
+)
+
+const raceenabled = false
+
+func raceAcquire(addr unsafe.Pointer) {
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}
diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..f1ec5dc4ee798dacc684d342b97c6b54fe538fa9
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/security_windows.go
@@ -0,0 +1,476 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const (
+	STANDARD_RIGHTS_REQUIRED = 0xf0000
+	STANDARD_RIGHTS_READ     = 0x20000
+	STANDARD_RIGHTS_WRITE    = 0x20000
+	STANDARD_RIGHTS_EXECUTE  = 0x20000
+	STANDARD_RIGHTS_ALL      = 0x1F0000
+)
+
+const (
+	NameUnknown          = 0
+	NameFullyQualifiedDN = 1
+	NameSamCompatible    = 2
+	NameDisplay          = 3
+	NameUniqueId         = 6
+	NameCanonical        = 7
+	NameUserPrincipal    = 8
+	NameCanonicalEx      = 9
+	NameServicePrincipal = 10
+	NameDnsDomain        = 12
+)
+
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
+//sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
+//sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
+
+// TranslateAccountName converts a directory service
+// object name from one format to another.
+func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
+	u, e := UTF16PtrFromString(username)
+	if e != nil {
+		return "", e
+	}
+	n := uint32(50)
+	for {
+		b := make([]uint16, n)
+		e = TranslateName(u, from, to, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b[:n]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}
+
+const (
+	// do not reorder
+	NetSetupUnknownStatus = iota
+	NetSetupUnjoined
+	NetSetupWorkgroupName
+	NetSetupDomainName
+)
+
+type UserInfo10 struct {
+	Name       *uint16
+	Comment    *uint16
+	UsrComment *uint16
+	FullName   *uint16
+}
+
+//sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
+//sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
+//sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+
+const (
+	// do not reorder
+	SidTypeUser = 1 + iota
+	SidTypeGroup
+	SidTypeDomain
+	SidTypeAlias
+	SidTypeWellKnownGroup
+	SidTypeDeletedAccount
+	SidTypeInvalid
+	SidTypeUnknown
+	SidTypeComputer
+	SidTypeLabel
+)
+
+type SidIdentifierAuthority struct {
+	Value [6]byte
+}
+
+var (
+	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
+	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
+	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
+	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
+	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
+	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
+	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
+)
+
+const (
+	SECURITY_NULL_RID                   = 0
+	SECURITY_WORLD_RID                  = 0
+	SECURITY_LOCAL_RID                  = 0
+	SECURITY_CREATOR_OWNER_RID          = 0
+	SECURITY_CREATOR_GROUP_RID          = 1
+	SECURITY_DIALUP_RID                 = 1
+	SECURITY_NETWORK_RID                = 2
+	SECURITY_BATCH_RID                  = 3
+	SECURITY_INTERACTIVE_RID            = 4
+	SECURITY_LOGON_IDS_RID              = 5
+	SECURITY_SERVICE_RID                = 6
+	SECURITY_LOCAL_SYSTEM_RID           = 18
+	SECURITY_BUILTIN_DOMAIN_RID         = 32
+	SECURITY_PRINCIPAL_SELF_RID         = 10
+	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
+	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
+	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
+	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
+	SECURITY_PROXY_RID                  = 0x8
+	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
+	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
+	SECURITY_AUTHENTICATED_USER_RID     = 0xb
+	SECURITY_RESTRICTED_CODE_RID        = 0xc
+	SECURITY_NT_NON_UNIQUE_RID          = 0x15
+)
+
+// Predefined domain-relative RIDs for local groups.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
+const (
+	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
+	DOMAIN_ALIAS_RID_USERS                          = 0x221
+	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
+	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
+	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
+	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
+	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
+	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
+	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
+	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
+	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
+	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
+	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
+	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
+	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0X22e
+	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
+	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
+	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
+	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
+	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
+	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
+	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
+	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
+	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
+	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
+)
+
+//sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
+//sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
+//sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
+//sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
+//sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
+//sys	AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
+//sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
+//sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
+
+// The security identifier (SID) structure is a variable-length
+// structure used to uniquely identify users or groups.
+type SID struct{}
+
+// StringToSid converts a string-format security identifier
+// sid into a valid, functional sid.
+func StringToSid(s string) (*SID, error) {
+	var sid *SID
+	p, e := UTF16PtrFromString(s)
+	if e != nil {
+		return nil, e
+	}
+	e = ConvertStringSidToSid(p, &sid)
+	if e != nil {
+		return nil, e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(sid)))
+	return sid.Copy()
+}
+
+// LookupSID retrieves a security identifier sid for the account
+// and the name of the domain on which the account was found.
+// System specify target computer to search.
+func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
+	if len(account) == 0 {
+		return nil, "", 0, syscall.EINVAL
+	}
+	acc, e := UTF16PtrFromString(account)
+	if e != nil {
+		return nil, "", 0, e
+	}
+	var sys *uint16
+	if len(system) > 0 {
+		sys, e = UTF16PtrFromString(system)
+		if e != nil {
+			return nil, "", 0, e
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]byte, n)
+		db := make([]uint16, dn)
+		sid = (*SID)(unsafe.Pointer(&b[0]))
+		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+		if e == nil {
+			return sid, UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, "", 0, e
+		}
+	}
+}
+
+// String converts sid to a string format
+// suitable for display, storage, or transmission.
+func (sid *SID) String() (string, error) {
+	var s *uint16
+	e := ConvertSidToStringSid(sid, &s)
+	if e != nil {
+		return "", e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(s)))
+	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
+}
+
+// Len returns the length, in bytes, of a valid security identifier sid.
+func (sid *SID) Len() int {
+	return int(GetLengthSid(sid))
+}
+
+// Copy creates a duplicate of security identifier sid.
+func (sid *SID) Copy() (*SID, error) {
+	b := make([]byte, sid.Len())
+	sid2 := (*SID)(unsafe.Pointer(&b[0]))
+	e := CopySid(uint32(len(b)), sid2, sid)
+	if e != nil {
+		return nil, e
+	}
+	return sid2, nil
+}
+
+// LookupAccount retrieves the name of the account for this sid
+// and the name of the first domain on which this sid is found.
+// System specify target computer to search for.
+func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
+	var sys *uint16
+	if len(system) > 0 {
+		sys, err = UTF16PtrFromString(system)
+		if err != nil {
+			return "", "", 0, err
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]uint16, n)
+		db := make([]uint16, dn)
+		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
+		if e == nil {
+			return UTF16ToString(b), UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return "", "", 0, e
+		}
+	}
+}
+
+const (
+	// do not reorder
+	TOKEN_ASSIGN_PRIMARY = 1 << iota
+	TOKEN_DUPLICATE
+	TOKEN_IMPERSONATE
+	TOKEN_QUERY
+	TOKEN_QUERY_SOURCE
+	TOKEN_ADJUST_PRIVILEGES
+	TOKEN_ADJUST_GROUPS
+	TOKEN_ADJUST_DEFAULT
+
+	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
+		TOKEN_ASSIGN_PRIMARY |
+		TOKEN_DUPLICATE |
+		TOKEN_IMPERSONATE |
+		TOKEN_QUERY |
+		TOKEN_QUERY_SOURCE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT
+	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
+	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT
+	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
+)
+
+const (
+	// do not reorder
+	TokenUser = 1 + iota
+	TokenGroups
+	TokenPrivileges
+	TokenOwner
+	TokenPrimaryGroup
+	TokenDefaultDacl
+	TokenSource
+	TokenType
+	TokenImpersonationLevel
+	TokenStatistics
+	TokenRestrictedSids
+	TokenSessionId
+	TokenGroupsAndPrivileges
+	TokenSessionReference
+	TokenSandBoxInert
+	TokenAuditPolicy
+	TokenOrigin
+	TokenElevationType
+	TokenLinkedToken
+	TokenElevation
+	TokenHasRestrictions
+	TokenAccessInformation
+	TokenVirtualizationAllowed
+	TokenVirtualizationEnabled
+	TokenIntegrityLevel
+	TokenUIAccess
+	TokenMandatoryPolicy
+	TokenLogonSid
+	MaxTokenInfoClass
+)
+
+type SIDAndAttributes struct {
+	Sid        *SID
+	Attributes uint32
+}
+
+type Tokenuser struct {
+	User SIDAndAttributes
+}
+
+type Tokenprimarygroup struct {
+	PrimaryGroup *SID
+}
+
+type Tokengroups struct {
+	GroupCount uint32
+	Groups     [1]SIDAndAttributes
+}
+
+// Authorization Functions
+//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
+//sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
+//sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
+//sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
+
+// An access token contains the security information for a logon session.
+// The system creates an access token when a user logs on, and every
+// process executed on behalf of the user has a copy of the token.
+// The token identifies the user, the user's groups, and the user's
+// privileges. The system uses the token to control access to securable
+// objects and to control the ability of the user to perform various
+// system-related operations on the local computer.
+type Token Handle
+
+// OpenCurrentProcessToken opens the access token
+// associated with current process.
+func OpenCurrentProcessToken() (Token, error) {
+	p, e := GetCurrentProcess()
+	if e != nil {
+		return 0, e
+	}
+	var t Token
+	e = OpenProcessToken(p, TOKEN_QUERY, &t)
+	if e != nil {
+		return 0, e
+	}
+	return t, nil
+}
+
+// Close releases access to access token.
+func (t Token) Close() error {
+	return CloseHandle(Handle(t))
+}
+
+// getInfo retrieves a specified type of information about an access token.
+func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
+	n := uint32(initSize)
+	for {
+		b := make([]byte, n)
+		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+		if e == nil {
+			return unsafe.Pointer(&b[0]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, e
+		}
+	}
+}
+
+// GetTokenUser retrieves access token t user account information.
+func (t Token) GetTokenUser() (*Tokenuser, error) {
+	i, e := t.getInfo(TokenUser, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenuser)(i), nil
+}
+
+// GetTokenGroups retrieves group accounts associated with access token t.
+func (t Token) GetTokenGroups() (*Tokengroups, error) {
+	i, e := t.getInfo(TokenGroups, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokengroups)(i), nil
+}
+
+// GetTokenPrimaryGroup retrieves access token t primary group information.
+// A pointer to a SID structure representing a group that will become
+// the primary group of any objects created by a process using this access token.
+func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
+	i, e := t.getInfo(TokenPrimaryGroup, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenprimarygroup)(i), nil
+}
+
+// GetUserProfileDirectory retrieves path to the
+// root directory of the access token t user's profile.
+func (t Token) GetUserProfileDirectory() (string, error) {
+	n := uint32(100)
+	for {
+		b := make([]uint16, n)
+		e := GetUserProfileDirectory(t, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}
+
+// IsMember reports whether the access token t is a member of the provided SID.
+func (t Token) IsMember(sid *SID) (bool, error) {
+	var b int32
+	if e := checkTokenMembership(t, sid, &b); e != nil {
+		return false, e
+	}
+	return b != 0, nil
+}
diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go
new file mode 100644
index 0000000000000000000000000000000000000000..a500dd7dfcf0a164eded614c9a0d0dba81223fad
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/service.go
@@ -0,0 +1,164 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+const (
+	SC_MANAGER_CONNECT            = 1
+	SC_MANAGER_CREATE_SERVICE     = 2
+	SC_MANAGER_ENUMERATE_SERVICE  = 4
+	SC_MANAGER_LOCK               = 8
+	SC_MANAGER_QUERY_LOCK_STATUS  = 16
+	SC_MANAGER_MODIFY_BOOT_CONFIG = 32
+	SC_MANAGER_ALL_ACCESS         = 0xf003f
+)
+
+//sys	OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
+
+const (
+	SERVICE_KERNEL_DRIVER       = 1
+	SERVICE_FILE_SYSTEM_DRIVER  = 2
+	SERVICE_ADAPTER             = 4
+	SERVICE_RECOGNIZER_DRIVER   = 8
+	SERVICE_WIN32_OWN_PROCESS   = 16
+	SERVICE_WIN32_SHARE_PROCESS = 32
+	SERVICE_WIN32               = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS
+	SERVICE_INTERACTIVE_PROCESS = 256
+	SERVICE_DRIVER              = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER
+	SERVICE_TYPE_ALL            = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS
+
+	SERVICE_BOOT_START   = 0
+	SERVICE_SYSTEM_START = 1
+	SERVICE_AUTO_START   = 2
+	SERVICE_DEMAND_START = 3
+	SERVICE_DISABLED     = 4
+
+	SERVICE_ERROR_IGNORE   = 0
+	SERVICE_ERROR_NORMAL   = 1
+	SERVICE_ERROR_SEVERE   = 2
+	SERVICE_ERROR_CRITICAL = 3
+
+	SC_STATUS_PROCESS_INFO = 0
+
+	SERVICE_STOPPED          = 1
+	SERVICE_START_PENDING    = 2
+	SERVICE_STOP_PENDING     = 3
+	SERVICE_RUNNING          = 4
+	SERVICE_CONTINUE_PENDING = 5
+	SERVICE_PAUSE_PENDING    = 6
+	SERVICE_PAUSED           = 7
+	SERVICE_NO_CHANGE        = 0xffffffff
+
+	SERVICE_ACCEPT_STOP                  = 1
+	SERVICE_ACCEPT_PAUSE_CONTINUE        = 2
+	SERVICE_ACCEPT_SHUTDOWN              = 4
+	SERVICE_ACCEPT_PARAMCHANGE           = 8
+	SERVICE_ACCEPT_NETBINDCHANGE         = 16
+	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32
+	SERVICE_ACCEPT_POWEREVENT            = 64
+	SERVICE_ACCEPT_SESSIONCHANGE         = 128
+
+	SERVICE_CONTROL_STOP                  = 1
+	SERVICE_CONTROL_PAUSE                 = 2
+	SERVICE_CONTROL_CONTINUE              = 3
+	SERVICE_CONTROL_INTERROGATE           = 4
+	SERVICE_CONTROL_SHUTDOWN              = 5
+	SERVICE_CONTROL_PARAMCHANGE           = 6
+	SERVICE_CONTROL_NETBINDADD            = 7
+	SERVICE_CONTROL_NETBINDREMOVE         = 8
+	SERVICE_CONTROL_NETBINDENABLE         = 9
+	SERVICE_CONTROL_NETBINDDISABLE        = 10
+	SERVICE_CONTROL_DEVICEEVENT           = 11
+	SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12
+	SERVICE_CONTROL_POWEREVENT            = 13
+	SERVICE_CONTROL_SESSIONCHANGE         = 14
+
+	SERVICE_ACTIVE    = 1
+	SERVICE_INACTIVE  = 2
+	SERVICE_STATE_ALL = 3
+
+	SERVICE_QUERY_CONFIG           = 1
+	SERVICE_CHANGE_CONFIG          = 2
+	SERVICE_QUERY_STATUS           = 4
+	SERVICE_ENUMERATE_DEPENDENTS   = 8
+	SERVICE_START                  = 16
+	SERVICE_STOP                   = 32
+	SERVICE_PAUSE_CONTINUE         = 64
+	SERVICE_INTERROGATE            = 128
+	SERVICE_USER_DEFINED_CONTROL   = 256
+	SERVICE_ALL_ACCESS             = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL
+	SERVICE_RUNS_IN_SYSTEM_PROCESS = 1
+	SERVICE_CONFIG_DESCRIPTION     = 1
+	SERVICE_CONFIG_FAILURE_ACTIONS = 2
+
+	NO_ERROR = 0
+
+	SC_ENUM_PROCESS_INFO = 0
+)
+
+type SERVICE_STATUS struct {
+	ServiceType             uint32
+	CurrentState            uint32
+	ControlsAccepted        uint32
+	Win32ExitCode           uint32
+	ServiceSpecificExitCode uint32
+	CheckPoint              uint32
+	WaitHint                uint32
+}
+
+type SERVICE_TABLE_ENTRY struct {
+	ServiceName *uint16
+	ServiceProc uintptr
+}
+
+type QUERY_SERVICE_CONFIG struct {
+	ServiceType      uint32
+	StartType        uint32
+	ErrorControl     uint32
+	BinaryPathName   *uint16
+	LoadOrderGroup   *uint16
+	TagId            uint32
+	Dependencies     *uint16
+	ServiceStartName *uint16
+	DisplayName      *uint16
+}
+
+type SERVICE_DESCRIPTION struct {
+	Description *uint16
+}
+
+type SERVICE_STATUS_PROCESS struct {
+	ServiceType             uint32
+	CurrentState            uint32
+	ControlsAccepted        uint32
+	Win32ExitCode           uint32
+	ServiceSpecificExitCode uint32
+	CheckPoint              uint32
+	WaitHint                uint32
+	ProcessId               uint32
+	ServiceFlags            uint32
+}
+
+type ENUM_SERVICE_STATUS_PROCESS struct {
+	ServiceName          *uint16
+	DisplayName          *uint16
+	ServiceStatusProcess SERVICE_STATUS_PROCESS
+}
+
+//sys	CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
+//sys	CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
+//sys	OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
+//sys	DeleteService(service Handle) (err error) = advapi32.DeleteService
+//sys	StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW
+//sys	QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus
+//sys	ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService
+//sys	StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW
+//sys	SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus
+//sys	ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW
+//sys	QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW
+//sys	ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W
+//sys	QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W
+//sys	EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW
diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go
new file mode 100644
index 0000000000000000000000000000000000000000..917cc2aae4e1b4163353fbdef21f591169977421
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/str.go
@@ -0,0 +1,22 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+	if val < 0 {
+		return "-" + itoa(-val)
+	}
+	var buf [32]byte // big enough for int64
+	i := len(buf) - 1
+	for val >= 10 {
+		buf[i] = byte(val%10 + '0')
+		i--
+		val /= 10
+	}
+	buf[i] = byte(val + '0')
+	return string(buf[i:])
+}
diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go
new file mode 100644
index 0000000000000000000000000000000000000000..af828a91bcf3fe6e2cee28cada66753543d8a5c8
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/syscall.go
@@ -0,0 +1,74 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package windows contains an interface to the low-level operating system
+// primitives. OS details vary depending on the underlying system, and
+// by default, godoc will display the OS-specific documentation for the current
+// system. If you want godoc to display syscall documentation for another
+// system, set $GOOS and $GOARCH to the desired system. For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+//
+// The primary use of this package is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net".  Use
+// those packages rather than this one if you can.
+//
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+//
+// These calls return err == nil to indicate success; otherwise
+// err represents an operating system error describing the failure and
+// holds a value of type syscall.Errno.
+package windows // import "golang.org/x/sys/windows"
+
+import (
+	"syscall"
+)
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, syscall.EINVAL
+		}
+	}
+	a := make([]byte, len(s)+1)
+	copy(a, s)
+	return a, nil
+}
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+	a, err := ByteSliceFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+	return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+	return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..1e9f4bb4a376285c9f1781e025d5b8e008fbc0d7
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -0,0 +1,1153 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows system calls.
+
+package windows
+
+import (
+	errorspkg "errors"
+	"sync"
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+type Handle uintptr
+
+const (
+	InvalidHandle = ^Handle(0)
+
+	// Flags for DefineDosDevice.
+	DDD_EXACT_MATCH_ON_REMOVE = 0x00000004
+	DDD_NO_BROADCAST_SYSTEM   = 0x00000008
+	DDD_RAW_TARGET_PATH       = 0x00000001
+	DDD_REMOVE_DEFINITION     = 0x00000002
+
+	// Return values for GetDriveType.
+	DRIVE_UNKNOWN     = 0
+	DRIVE_NO_ROOT_DIR = 1
+	DRIVE_REMOVABLE   = 2
+	DRIVE_FIXED       = 3
+	DRIVE_REMOTE      = 4
+	DRIVE_CDROM       = 5
+	DRIVE_RAMDISK     = 6
+
+	// File system flags from GetVolumeInformation and GetVolumeInformationByHandle.
+	FILE_CASE_SENSITIVE_SEARCH        = 0x00000001
+	FILE_CASE_PRESERVED_NAMES         = 0x00000002
+	FILE_FILE_COMPRESSION             = 0x00000010
+	FILE_DAX_VOLUME                   = 0x20000000
+	FILE_NAMED_STREAMS                = 0x00040000
+	FILE_PERSISTENT_ACLS              = 0x00000008
+	FILE_READ_ONLY_VOLUME             = 0x00080000
+	FILE_SEQUENTIAL_WRITE_ONCE        = 0x00100000
+	FILE_SUPPORTS_ENCRYPTION          = 0x00020000
+	FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000
+	FILE_SUPPORTS_HARD_LINKS          = 0x00400000
+	FILE_SUPPORTS_OBJECT_IDS          = 0x00010000
+	FILE_SUPPORTS_OPEN_BY_FILE_ID     = 0x01000000
+	FILE_SUPPORTS_REPARSE_POINTS      = 0x00000080
+	FILE_SUPPORTS_SPARSE_FILES        = 0x00000040
+	FILE_SUPPORTS_TRANSACTIONS        = 0x00200000
+	FILE_SUPPORTS_USN_JOURNAL         = 0x02000000
+	FILE_UNICODE_ON_DISK              = 0x00000004
+	FILE_VOLUME_IS_COMPRESSED         = 0x00008000
+	FILE_VOLUME_QUOTAS                = 0x00000020
+)
+
+// StringToUTF16 is deprecated. Use UTF16FromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16(s string) []uint16 {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		panic("windows: string with NUL passed to StringToUTF16")
+	}
+	return a
+}
+
+// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
+// s, with a terminating NUL added. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func UTF16FromString(s string) ([]uint16, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, syscall.EINVAL
+		}
+	}
+	return utf16.Encode([]rune(s + "\x00")), nil
+}
+
+// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
+// with a terminating NUL removed.
+func UTF16ToString(s []uint16) string {
+	for i, v := range s {
+		if v == 0 {
+			s = s[0:i]
+			break
+		}
+	}
+	return string(utf16.Decode(s))
+}
+
+// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
+
+// UTF16PtrFromString returns pointer to the UTF-16 encoding of
+// the UTF-8 string s, with a terminating NUL added. If s
+// contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
+func UTF16PtrFromString(s string) (*uint16, error) {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+func Getpagesize() int { return 4096 }
+
+// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
+// This is useful when interoperating with Windows code requiring callbacks.
+func NewCallback(fn interface{}) uintptr {
+	return syscall.NewCallback(fn)
+}
+
+// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
+// This is useful when interoperating with Windows code requiring callbacks.
+func NewCallbackCDecl(fn interface{}) uintptr {
+	return syscall.NewCallbackCDecl(fn)
+}
+
+// windows api calls
+
+//sys	GetLastError() (lasterr error)
+//sys	LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
+//sys	LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW
+//sys	FreeLibrary(handle Handle) (err error)
+//sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
+//sys	GetVersion() (ver uint32, err error)
+//sys	FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
+//sys	ExitProcess(exitcode uint32)
+//sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
+//sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
+//sys	CloseHandle(handle Handle) (err error)
+//sys	GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle]
+//sys	SetStdHandle(stdhandle uint32, handle Handle) (err error)
+//sys	findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
+//sys	findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
+//sys	FindClose(handle Handle) (err error)
+//sys	GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
+//sys	GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
+//sys	SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
+//sys	CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
+//sys	RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
+//sys	DeleteFile(path *uint16) (err error) = DeleteFileW
+//sys	MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
+//sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
+//sys	GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
+//sys	GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
+//sys	SetEndOfFile(handle Handle) (err error)
+//sys	GetSystemTimeAsFileTime(time *Filetime)
+//sys	GetSystemTimePreciseAsFileTime(time *Filetime)
+//sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
+//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
+//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
+//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
+//sys	CancelIo(s Handle) (err error)
+//sys	CancelIoEx(s Handle, o *Overlapped) (err error)
+//sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+//sys	OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
+//sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
+//sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
+//sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
+//sys	GetCurrentProcess() (pseudoHandle Handle, err error)
+//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
+//sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
+//sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
+//sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
+//sys	CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
+//sys	GetFileType(filehandle Handle) (n uint32, err error)
+//sys	CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
+//sys	CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
+//sys	CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
+//sys	GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
+//sys	FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
+//sys	GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
+//sys	SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
+//sys	SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
+//sys	GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
+//sys	SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
+//sys	GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
+//sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
+//sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
+//sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
+//sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
+//sys	FlushFileBuffers(handle Handle) (err error)
+//sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
+//sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
+//sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
+//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
+//sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
+//sys	UnmapViewOfFile(addr uintptr) (err error)
+//sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
+//sys	VirtualLock(addr uintptr, length uintptr) (err error)
+//sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
+//sys	VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc
+//sys	VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree
+//sys	VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect
+//sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
+//sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
+//sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
+//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
+//sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
+//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
+//sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
+//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
+//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
+//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
+//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
+//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
+//sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
+//sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
+//sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
+//sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
+//sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
+//sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
+//sys	SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
+//sys	GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
+//sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
+//sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
+//sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
+//sys	Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
+//sys	Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
+//sys	DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+//sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
+//sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+//sys	GetCurrentThreadId() (id uint32)
+//sys	CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
+//sys	CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW
+//sys	OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW
+//sys	SetEvent(event Handle) (err error) = kernel32.SetEvent
+//sys	ResetEvent(event Handle) (err error) = kernel32.ResetEvent
+//sys	PulseEvent(event Handle) (err error) = kernel32.PulseEvent
+
+// Volume Management Functions
+//sys	DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW
+//sys	DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW
+//sys	FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW
+//sys	FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW
+//sys	FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW
+//sys	FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW
+//sys	FindVolumeClose(findVolume Handle) (err error)
+//sys	FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error)
+//sys	GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW
+//sys	GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0]
+//sys	GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW
+//sys	GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW
+//sys	GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW
+//sys	GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW
+//sys	GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW
+//sys	GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW
+//sys	QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW
+//sys	SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW
+//sys	SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW
+
+// syscall interface implementation for other packages
+
+// GetProcAddressByOrdinal retrieves the address of the exported
+// function from module by ordinal.
+func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) {
+	r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
+	proc = uintptr(r0)
+	if proc == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Exit(code int) { ExitProcess(uint32(code)) }
+
+func makeInheritSa() *SecurityAttributes {
+	var sa SecurityAttributes
+	sa.Length = uint32(unsafe.Sizeof(sa))
+	sa.InheritHandle = 1
+	return &sa
+}
+
+func Open(path string, mode int, perm uint32) (fd Handle, err error) {
+	if len(path) == 0 {
+		return InvalidHandle, ERROR_FILE_NOT_FOUND
+	}
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return InvalidHandle, err
+	}
+	var access uint32
+	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
+	case O_RDONLY:
+		access = GENERIC_READ
+	case O_WRONLY:
+		access = GENERIC_WRITE
+	case O_RDWR:
+		access = GENERIC_READ | GENERIC_WRITE
+	}
+	if mode&O_CREAT != 0 {
+		access |= GENERIC_WRITE
+	}
+	if mode&O_APPEND != 0 {
+		access &^= GENERIC_WRITE
+		access |= FILE_APPEND_DATA
+	}
+	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
+	var sa *SecurityAttributes
+	if mode&O_CLOEXEC == 0 {
+		sa = makeInheritSa()
+	}
+	var createmode uint32
+	switch {
+	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
+		createmode = CREATE_NEW
+	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
+		createmode = CREATE_ALWAYS
+	case mode&O_CREAT == O_CREAT:
+		createmode = OPEN_ALWAYS
+	case mode&O_TRUNC == O_TRUNC:
+		createmode = TRUNCATE_EXISTING
+	default:
+		createmode = OPEN_EXISTING
+	}
+	h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
+	return h, e
+}
+
+func Read(fd Handle, p []byte) (n int, err error) {
+	var done uint32
+	e := ReadFile(fd, p, &done, nil)
+	if e != nil {
+		if e == ERROR_BROKEN_PIPE {
+			// NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
+			return 0, nil
+		}
+		return 0, e
+	}
+	if raceenabled {
+		if done > 0 {
+			raceWriteRange(unsafe.Pointer(&p[0]), int(done))
+		}
+		raceAcquire(unsafe.Pointer(&ioSync))
+	}
+	return int(done), nil
+}
+
+func Write(fd Handle, p []byte) (n int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	var done uint32
+	e := WriteFile(fd, p, &done, nil)
+	if e != nil {
+		return 0, e
+	}
+	if raceenabled && done > 0 {
+		raceReadRange(unsafe.Pointer(&p[0]), int(done))
+	}
+	return int(done), nil
+}
+
+var ioSync int64
+
+func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
+	var w uint32
+	switch whence {
+	case 0:
+		w = FILE_BEGIN
+	case 1:
+		w = FILE_CURRENT
+	case 2:
+		w = FILE_END
+	}
+	hi := int32(offset >> 32)
+	lo := int32(offset)
+	// use GetFileType to check pipe, pipe can't do seek
+	ft, _ := GetFileType(fd)
+	if ft == FILE_TYPE_PIPE {
+		return 0, syscall.EPIPE
+	}
+	rlo, e := SetFilePointer(fd, lo, &hi, w)
+	if e != nil {
+		return 0, e
+	}
+	return int64(hi)<<32 + int64(rlo), nil
+}
+
+func Close(fd Handle) (err error) {
+	return CloseHandle(fd)
+}
+
+var (
+	Stdin  = getStdHandle(STD_INPUT_HANDLE)
+	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
+	Stderr = getStdHandle(STD_ERROR_HANDLE)
+)
+
+func getStdHandle(stdhandle uint32) (fd Handle) {
+	r, _ := GetStdHandle(stdhandle)
+	CloseOnExec(r)
+	return r
+}
+
+const ImplementsGetwd = true
+
+func Getwd() (wd string, err error) {
+	b := make([]uint16, 300)
+	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Chdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return SetCurrentDirectory(pathp)
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return CreateDirectory(pathp, nil)
+}
+
+func Rmdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return RemoveDirectory(pathp)
+}
+
+func Unlink(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return DeleteFile(pathp)
+}
+
+func Rename(oldpath, newpath string) (err error) {
+	from, err := UTF16PtrFromString(oldpath)
+	if err != nil {
+		return err
+	}
+	to, err := UTF16PtrFromString(newpath)
+	if err != nil {
+		return err
+	}
+	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
+}
+
+func ComputerName() (name string, err error) {
+	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
+	b := make([]uint16, n)
+	e := GetComputerName(&b[0], &n)
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Ftruncate(fd Handle, length int64) (err error) {
+	curoffset, e := Seek(fd, 0, 1)
+	if e != nil {
+		return e
+	}
+	defer Seek(fd, curoffset, 0)
+	_, e = Seek(fd, length, 0)
+	if e != nil {
+		return e
+	}
+	e = SetEndOfFile(fd)
+	if e != nil {
+		return e
+	}
+	return nil
+}
+
+func Gettimeofday(tv *Timeval) (err error) {
+	var ft Filetime
+	GetSystemTimeAsFileTime(&ft)
+	*tv = NsecToTimeval(ft.Nanoseconds())
+	return nil
+}
+
+func Pipe(p []Handle) (err error) {
+	if len(p) != 2 {
+		return syscall.EINVAL
+	}
+	var r, w Handle
+	e := CreatePipe(&r, &w, makeInheritSa(), 0)
+	if e != nil {
+		return e
+	}
+	p[0] = r
+	p[1] = w
+	return nil
+}
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return syscall.EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(tv[0].Nanoseconds())
+	w := NsecToFiletime(tv[1].Nanoseconds())
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+	if len(ts) != 2 {
+		return syscall.EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(TimespecToNsec(ts[0]))
+	w := NsecToFiletime(TimespecToNsec(ts[1]))
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func Fsync(fd Handle) (err error) {
+	return FlushFileBuffers(fd)
+}
+
+func Chmod(path string, mode uint32) (err error) {
+	if mode == 0 {
+		return syscall.EINVAL
+	}
+	p, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	attrs, e := GetFileAttributes(p)
+	if e != nil {
+		return e
+	}
+	if mode&S_IWRITE != 0 {
+		attrs &^= FILE_ATTRIBUTE_READONLY
+	} else {
+		attrs |= FILE_ATTRIBUTE_READONLY
+	}
+	return SetFileAttributes(p, attrs)
+}
+
+func LoadGetSystemTimePreciseAsFileTime() error {
+	return procGetSystemTimePreciseAsFileTime.Find()
+}
+
+func LoadCancelIoEx() error {
+	return procCancelIoEx.Find()
+}
+
+func LoadSetFileCompletionNotificationModes() error {
+	return procSetFileCompletionNotificationModes.Find()
+}
+
+// net api calls
+
+const socket_error = uintptr(^uint32(0))
+
+//sys	WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
+//sys	WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
+//sys	WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
+//sys	socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
+//sys	Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
+//sys	Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
+//sys	bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
+//sys	connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
+//sys	getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
+//sys	getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
+//sys	listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
+//sys	shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
+//sys	Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
+//sys	AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
+//sys	GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
+//sys	WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
+//sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
+//sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
+//sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
+//sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
+//sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
+//sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
+//sys	GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
+//sys	DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
+//sys	DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
+//sys	DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
+//sys	GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
+//sys	FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
+//sys	GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
+//sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
+//sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
+//sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
+//sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
+//sys	GetACP() (acp uint32) = kernel32.GetACP
+//sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type RawSockaddrInet4 struct {
+	Family uint16
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+	Family   uint16
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [96]int8
+}
+
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+	raw  RawSockaddrInet4
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+	raw    RawSockaddrInet6
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrUnix struct {
+	Name string
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
+	// TODO(brainman): implement SockaddrUnix.sockaddr()
+	return nil, 0, syscall.EWINDOWS
+}
+
+func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
+	switch rsa.Addr.Family {
+	case AF_UNIX:
+		return nil, syscall.EWINDOWS
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, syscall.EAFNOSUPPORT
+}
+
+func Socket(domain, typ, proto int) (fd Handle, err error) {
+	if domain == AF_INET6 && SocketDisableIPv6 {
+		return InvalidHandle, syscall.EAFNOSUPPORT
+	}
+	return socket(int32(domain), int32(typ), int32(proto))
+}
+
+func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
+	v := int32(value)
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
+}
+
+func Bind(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return bind(fd, ptr, n)
+}
+
+func Connect(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connect(fd, ptr, n)
+}
+
+func Getsockname(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getsockname(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Getpeername(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getpeername(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Listen(s Handle, n int) (err error) {
+	return listen(s, int32(n))
+}
+
+func Shutdown(fd Handle, how int) (err error) {
+	return shutdown(fd, int32(how))
+}
+
+func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
+	rsa, l, err := to.sockaddr()
+	if err != nil {
+		return err
+	}
+	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
+}
+
+func LoadGetAddrInfo() error {
+	return procGetAddrInfoW.Find()
+}
+
+var connectExFunc struct {
+	once sync.Once
+	addr uintptr
+	err  error
+}
+
+func LoadConnectEx() error {
+	connectExFunc.once.Do(func() {
+		var s Handle
+		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
+		if connectExFunc.err != nil {
+			return
+		}
+		defer CloseHandle(s)
+		var n uint32
+		connectExFunc.err = WSAIoctl(s,
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
+			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
+			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
+			uint32(unsafe.Sizeof(connectExFunc.addr)),
+			&n, nil, 0)
+	})
+	return connectExFunc.err
+}
+
+func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
+	err := LoadConnectEx()
+	if err != nil {
+		return errorspkg.New("failed to find ConnectEx: " + err.Error())
+	}
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+var sendRecvMsgFunc struct {
+	once     sync.Once
+	sendAddr uintptr
+	recvAddr uintptr
+	err      error
+}
+
+func loadWSASendRecvMsg() error {
+	sendRecvMsgFunc.once.Do(func() {
+		var s Handle
+		s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+		if sendRecvMsgFunc.err != nil {
+			return
+		}
+		defer CloseHandle(s)
+		var n uint32
+		sendRecvMsgFunc.err = WSAIoctl(s,
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
+			uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
+			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
+			uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
+			&n, nil, 0)
+		if sendRecvMsgFunc.err != nil {
+			return
+		}
+		sendRecvMsgFunc.err = WSAIoctl(s,
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
+			uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
+			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
+			uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
+			&n, nil, 0)
+	})
+	return sendRecvMsgFunc.err
+}
+
+func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error {
+	err := loadWSASendRecvMsg()
+	if err != nil {
+		return err
+	}
+	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return err
+}
+
+func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error {
+	err := loadWSASendRecvMsg()
+	if err != nil {
+		return err
+	}
+	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return err
+}
+
+// Invented structures to support what package os expects.
+type Rusage struct {
+	CreationTime Filetime
+	ExitTime     Filetime
+	KernelTime   Filetime
+	UserTime     Filetime
+}
+
+type WaitStatus struct {
+	ExitCode uint32
+}
+
+func (w WaitStatus) Exited() bool { return true }
+
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
+
+func (w WaitStatus) Signal() Signal { return -1 }
+
+func (w WaitStatus) CoreDump() bool { return false }
+
+func (w WaitStatus) Stopped() bool { return false }
+
+func (w WaitStatus) Continued() bool { return false }
+
+func (w WaitStatus) StopSignal() Signal { return -1 }
+
+func (w WaitStatus) Signaled() bool { return false }
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+// Timespec is an invented structure on Windows, but here for
+// consistency with the corresponding package for other operating systems.
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = nsec / 1e9
+	ts.Nsec = nsec % 1e9
+	return
+}
+
+// TODO(brainman): fix all needed for net
+
+func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS }
+func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
+	return 0, nil, syscall.EWINDOWS
+}
+func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return syscall.EWINDOWS }
+func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS }
+
+// The Linger struct is wrong but we only noticed after Go 1.
+// sysLinger is the real system call structure.
+
+// BUG(brainman): The definition of Linger is not appropriate for direct use
+// with Setsockopt and Getsockopt.
+// Use SetsockoptLinger instead.
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type sysLinger struct {
+	Onoff  uint16
+	Linger uint16
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
+
+func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
+	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
+}
+
+func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
+}
+func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+}
+func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
+	return syscall.EWINDOWS
+}
+
+func Getpid() (pid int) { return int(getCurrentProcessId()) }
+
+func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
+	// NOTE(rsc): The Win32finddata struct is wrong for the system call:
+	// the two paths are each one uint16 short. Use the correct struct,
+	// a win32finddata1, and then copy the results out.
+	// There is no loss of expressivity here, because the final
+	// uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
+	// For Go 1.1, we might avoid the allocation of win32finddata1 here
+	// by adding a final Bug [2]uint16 field to the struct and then
+	// adjusting the fields in the result directly.
+	var data1 win32finddata1
+	handle, err = findFirstFile1(name, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func FindNextFile(handle Handle, data *Win32finddata) (err error) {
+	var data1 win32finddata1
+	err = findNextFile1(handle, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func getProcessEntry(pid int) (*ProcessEntry32, error) {
+	snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+	if err != nil {
+		return nil, err
+	}
+	defer CloseHandle(snapshot)
+	var procEntry ProcessEntry32
+	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+	if err = Process32First(snapshot, &procEntry); err != nil {
+		return nil, err
+	}
+	for {
+		if procEntry.ProcessID == uint32(pid) {
+			return &procEntry, nil
+		}
+		err = Process32Next(snapshot, &procEntry)
+		if err != nil {
+			return nil, err
+		}
+	}
+}
+
+func Getppid() (ppid int) {
+	pe, err := getProcessEntry(Getpid())
+	if err != nil {
+		return -1
+	}
+	return int(pe.ParentProcessID)
+}
+
+// TODO(brainman): fix all needed for os
+func Fchdir(fd Handle) (err error)             { return syscall.EWINDOWS }
+func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS }
+func Symlink(path, link string) (err error)    { return syscall.EWINDOWS }
+
+func Fchmod(fd Handle, mode uint32) (err error)        { return syscall.EWINDOWS }
+func Chown(path string, uid int, gid int) (err error)  { return syscall.EWINDOWS }
+func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
+func Fchown(fd Handle, uid int, gid int) (err error)   { return syscall.EWINDOWS }
+
+func Getuid() (uid int)                  { return -1 }
+func Geteuid() (euid int)                { return -1 }
+func Getgid() (gid int)                  { return -1 }
+func Getegid() (egid int)                { return -1 }
+func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
+
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+	if 0 <= s && int(s) < len(signals) {
+		str := signals[s]
+		if str != "" {
+			return str
+		}
+	}
+	return "signal " + itoa(int(s))
+}
+
+func LoadCreateSymbolicLink() error {
+	return procCreateSymbolicLinkW.Find()
+}
+
+// Readlink returns the destination of the named symbolic link.
+func Readlink(path string, buf []byte) (n int, err error) {
+	fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if err != nil {
+		return -1, err
+	}
+	defer CloseHandle(fd)
+
+	rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+	var bytesReturned uint32
+	err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
+	if err != nil {
+		return -1, err
+	}
+
+	rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
+	var s string
+	switch rdb.ReparseTag {
+	case IO_REPARSE_TAG_SYMLINK:
+		data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+	case IO_REPARSE_TAG_MOUNT_POINT:
+		data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+	default:
+		// the path is not a symlink or junction but another type of reparse
+		// point
+		return -1, syscall.ENOENT
+	}
+	n = copy(buf, []byte(s))
+
+	return n, nil
+}
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..52c2037b68edb05750eca08ff8233f295caa48c3
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -0,0 +1,1333 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import "syscall"
+
+const (
+	// Windows errors.
+	ERROR_FILE_NOT_FOUND         syscall.Errno = 2
+	ERROR_PATH_NOT_FOUND         syscall.Errno = 3
+	ERROR_ACCESS_DENIED          syscall.Errno = 5
+	ERROR_NO_MORE_FILES          syscall.Errno = 18
+	ERROR_HANDLE_EOF             syscall.Errno = 38
+	ERROR_NETNAME_DELETED        syscall.Errno = 64
+	ERROR_FILE_EXISTS            syscall.Errno = 80
+	ERROR_BROKEN_PIPE            syscall.Errno = 109
+	ERROR_BUFFER_OVERFLOW        syscall.Errno = 111
+	ERROR_INSUFFICIENT_BUFFER    syscall.Errno = 122
+	ERROR_MOD_NOT_FOUND          syscall.Errno = 126
+	ERROR_PROC_NOT_FOUND         syscall.Errno = 127
+	ERROR_ALREADY_EXISTS         syscall.Errno = 183
+	ERROR_ENVVAR_NOT_FOUND       syscall.Errno = 203
+	ERROR_MORE_DATA              syscall.Errno = 234
+	ERROR_OPERATION_ABORTED      syscall.Errno = 995
+	ERROR_IO_PENDING             syscall.Errno = 997
+	ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066
+	ERROR_NOT_FOUND              syscall.Errno = 1168
+	ERROR_PRIVILEGE_NOT_HELD     syscall.Errno = 1314
+	WSAEACCES                    syscall.Errno = 10013
+	WSAEMSGSIZE                  syscall.Errno = 10040
+	WSAECONNRESET                syscall.Errno = 10054
+)
+
+const (
+	// Invented values to support what package os expects.
+	O_RDONLY   = 0x00000
+	O_WRONLY   = 0x00001
+	O_RDWR     = 0x00002
+	O_CREAT    = 0x00040
+	O_EXCL     = 0x00080
+	O_NOCTTY   = 0x00100
+	O_TRUNC    = 0x00200
+	O_NONBLOCK = 0x00800
+	O_APPEND   = 0x00400
+	O_SYNC     = 0x01000
+	O_ASYNC    = 0x02000
+	O_CLOEXEC  = 0x80000
+)
+
+const (
+	// More invented values for signals
+	SIGHUP  = Signal(0x1)
+	SIGINT  = Signal(0x2)
+	SIGQUIT = Signal(0x3)
+	SIGILL  = Signal(0x4)
+	SIGTRAP = Signal(0x5)
+	SIGABRT = Signal(0x6)
+	SIGBUS  = Signal(0x7)
+	SIGFPE  = Signal(0x8)
+	SIGKILL = Signal(0x9)
+	SIGSEGV = Signal(0xb)
+	SIGPIPE = Signal(0xd)
+	SIGALRM = Signal(0xe)
+	SIGTERM = Signal(0xf)
+)
+
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/breakpoint trap",
+	6:  "aborted",
+	7:  "bus error",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "user defined signal 1",
+	11: "segmentation fault",
+	12: "user defined signal 2",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+}
+
+const (
+	GENERIC_READ    = 0x80000000
+	GENERIC_WRITE   = 0x40000000
+	GENERIC_EXECUTE = 0x20000000
+	GENERIC_ALL     = 0x10000000
+
+	FILE_LIST_DIRECTORY   = 0x00000001
+	FILE_APPEND_DATA      = 0x00000004
+	FILE_WRITE_ATTRIBUTES = 0x00000100
+
+	FILE_SHARE_READ              = 0x00000001
+	FILE_SHARE_WRITE             = 0x00000002
+	FILE_SHARE_DELETE            = 0x00000004
+	FILE_ATTRIBUTE_READONLY      = 0x00000001
+	FILE_ATTRIBUTE_HIDDEN        = 0x00000002
+	FILE_ATTRIBUTE_SYSTEM        = 0x00000004
+	FILE_ATTRIBUTE_DIRECTORY     = 0x00000010
+	FILE_ATTRIBUTE_ARCHIVE       = 0x00000020
+	FILE_ATTRIBUTE_NORMAL        = 0x00000080
+	FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
+
+	INVALID_FILE_ATTRIBUTES = 0xffffffff
+
+	CREATE_NEW        = 1
+	CREATE_ALWAYS     = 2
+	OPEN_EXISTING     = 3
+	OPEN_ALWAYS       = 4
+	TRUNCATE_EXISTING = 5
+
+	FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
+	FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000
+	FILE_FLAG_OVERLAPPED         = 0x40000000
+
+	HANDLE_FLAG_INHERIT    = 0x00000001
+	STARTF_USESTDHANDLES   = 0x00000100
+	STARTF_USESHOWWINDOW   = 0x00000001
+	DUPLICATE_CLOSE_SOURCE = 0x00000001
+	DUPLICATE_SAME_ACCESS  = 0x00000002
+
+	STD_INPUT_HANDLE  = -10 & (1<<32 - 1)
+	STD_OUTPUT_HANDLE = -11 & (1<<32 - 1)
+	STD_ERROR_HANDLE  = -12 & (1<<32 - 1)
+
+	FILE_BEGIN   = 0
+	FILE_CURRENT = 1
+	FILE_END     = 2
+
+	LANG_ENGLISH       = 0x09
+	SUBLANG_ENGLISH_US = 0x01
+
+	FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
+	FORMAT_MESSAGE_IGNORE_INSERTS  = 512
+	FORMAT_MESSAGE_FROM_STRING     = 1024
+	FORMAT_MESSAGE_FROM_HMODULE    = 2048
+	FORMAT_MESSAGE_FROM_SYSTEM     = 4096
+	FORMAT_MESSAGE_ARGUMENT_ARRAY  = 8192
+	FORMAT_MESSAGE_MAX_WIDTH_MASK  = 255
+
+	MAX_PATH      = 260
+	MAX_LONG_PATH = 32768
+
+	MAX_COMPUTERNAME_LENGTH = 15
+
+	TIME_ZONE_ID_UNKNOWN  = 0
+	TIME_ZONE_ID_STANDARD = 1
+
+	TIME_ZONE_ID_DAYLIGHT = 2
+	IGNORE                = 0
+	INFINITE              = 0xffffffff
+
+	WAIT_TIMEOUT   = 258
+	WAIT_ABANDONED = 0x00000080
+	WAIT_OBJECT_0  = 0x00000000
+	WAIT_FAILED    = 0xFFFFFFFF
+
+	PROCESS_TERMINATE         = 1
+	PROCESS_QUERY_INFORMATION = 0x00000400
+	SYNCHRONIZE               = 0x00100000
+
+	FILE_MAP_COPY    = 0x01
+	FILE_MAP_WRITE   = 0x02
+	FILE_MAP_READ    = 0x04
+	FILE_MAP_EXECUTE = 0x20
+
+	CTRL_C_EVENT     = 0
+	CTRL_BREAK_EVENT = 1
+
+	// Windows reserves errors >= 1<<29 for application use.
+	APPLICATION_ERROR = 1 << 29
+)
+
+const (
+	// Process creation flags.
+	CREATE_BREAKAWAY_FROM_JOB        = 0x01000000
+	CREATE_DEFAULT_ERROR_MODE        = 0x04000000
+	CREATE_NEW_CONSOLE               = 0x00000010
+	CREATE_NEW_PROCESS_GROUP         = 0x00000200
+	CREATE_NO_WINDOW                 = 0x08000000
+	CREATE_PROTECTED_PROCESS         = 0x00040000
+	CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000
+	CREATE_SEPARATE_WOW_VDM          = 0x00000800
+	CREATE_SHARED_WOW_VDM            = 0x00001000
+	CREATE_SUSPENDED                 = 0x00000004
+	CREATE_UNICODE_ENVIRONMENT       = 0x00000400
+	DEBUG_ONLY_THIS_PROCESS          = 0x00000002
+	DEBUG_PROCESS                    = 0x00000001
+	DETACHED_PROCESS                 = 0x00000008
+	EXTENDED_STARTUPINFO_PRESENT     = 0x00080000
+	INHERIT_PARENT_AFFINITY          = 0x00010000
+)
+
+const (
+	// flags for CreateToolhelp32Snapshot
+	TH32CS_SNAPHEAPLIST = 0x01
+	TH32CS_SNAPPROCESS  = 0x02
+	TH32CS_SNAPTHREAD   = 0x04
+	TH32CS_SNAPMODULE   = 0x08
+	TH32CS_SNAPMODULE32 = 0x10
+	TH32CS_SNAPALL      = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD
+	TH32CS_INHERIT      = 0x80000000
+)
+
+const (
+	// filters for ReadDirectoryChangesW
+	FILE_NOTIFY_CHANGE_FILE_NAME   = 0x001
+	FILE_NOTIFY_CHANGE_DIR_NAME    = 0x002
+	FILE_NOTIFY_CHANGE_ATTRIBUTES  = 0x004
+	FILE_NOTIFY_CHANGE_SIZE        = 0x008
+	FILE_NOTIFY_CHANGE_LAST_WRITE  = 0x010
+	FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020
+	FILE_NOTIFY_CHANGE_CREATION    = 0x040
+	FILE_NOTIFY_CHANGE_SECURITY    = 0x100
+)
+
+const (
+	// do not reorder
+	FILE_ACTION_ADDED = iota + 1
+	FILE_ACTION_REMOVED
+	FILE_ACTION_MODIFIED
+	FILE_ACTION_RENAMED_OLD_NAME
+	FILE_ACTION_RENAMED_NEW_NAME
+)
+
+const (
+	// wincrypt.h
+	PROV_RSA_FULL                    = 1
+	PROV_RSA_SIG                     = 2
+	PROV_DSS                         = 3
+	PROV_FORTEZZA                    = 4
+	PROV_MS_EXCHANGE                 = 5
+	PROV_SSL                         = 6
+	PROV_RSA_SCHANNEL                = 12
+	PROV_DSS_DH                      = 13
+	PROV_EC_ECDSA_SIG                = 14
+	PROV_EC_ECNRA_SIG                = 15
+	PROV_EC_ECDSA_FULL               = 16
+	PROV_EC_ECNRA_FULL               = 17
+	PROV_DH_SCHANNEL                 = 18
+	PROV_SPYRUS_LYNKS                = 20
+	PROV_RNG                         = 21
+	PROV_INTEL_SEC                   = 22
+	PROV_REPLACE_OWF                 = 23
+	PROV_RSA_AES                     = 24
+	CRYPT_VERIFYCONTEXT              = 0xF0000000
+	CRYPT_NEWKEYSET                  = 0x00000008
+	CRYPT_DELETEKEYSET               = 0x00000010
+	CRYPT_MACHINE_KEYSET             = 0x00000020
+	CRYPT_SILENT                     = 0x00000040
+	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
+
+	USAGE_MATCH_TYPE_AND = 0
+	USAGE_MATCH_TYPE_OR  = 1
+
+	X509_ASN_ENCODING   = 0x00000001
+	PKCS_7_ASN_ENCODING = 0x00010000
+
+	CERT_STORE_PROV_MEMORY = 2
+
+	CERT_STORE_ADD_ALWAYS = 4
+
+	CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
+
+	CERT_TRUST_NO_ERROR                          = 0x00000000
+	CERT_TRUST_IS_NOT_TIME_VALID                 = 0x00000001
+	CERT_TRUST_IS_REVOKED                        = 0x00000004
+	CERT_TRUST_IS_NOT_SIGNATURE_VALID            = 0x00000008
+	CERT_TRUST_IS_NOT_VALID_FOR_USAGE            = 0x00000010
+	CERT_TRUST_IS_UNTRUSTED_ROOT                 = 0x00000020
+	CERT_TRUST_REVOCATION_STATUS_UNKNOWN         = 0x00000040
+	CERT_TRUST_IS_CYCLIC                         = 0x00000080
+	CERT_TRUST_INVALID_EXTENSION                 = 0x00000100
+	CERT_TRUST_INVALID_POLICY_CONSTRAINTS        = 0x00000200
+	CERT_TRUST_INVALID_BASIC_CONSTRAINTS         = 0x00000400
+	CERT_TRUST_INVALID_NAME_CONSTRAINTS          = 0x00000800
+	CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000
+	CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT   = 0x00002000
+	CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
+	CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT      = 0x00008000
+	CERT_TRUST_IS_OFFLINE_REVOCATION             = 0x01000000
+	CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY          = 0x02000000
+	CERT_TRUST_IS_EXPLICIT_DISTRUST              = 0x04000000
+	CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT    = 0x08000000
+
+	CERT_CHAIN_POLICY_BASE              = 1
+	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
+	CERT_CHAIN_POLICY_AUTHENTICODE_TS   = 3
+	CERT_CHAIN_POLICY_SSL               = 4
+	CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5
+	CERT_CHAIN_POLICY_NT_AUTH           = 6
+	CERT_CHAIN_POLICY_MICROSOFT_ROOT    = 7
+	CERT_CHAIN_POLICY_EV                = 8
+
+	CERT_E_EXPIRED       = 0x800B0101
+	CERT_E_ROLE          = 0x800B0103
+	CERT_E_PURPOSE       = 0x800B0106
+	CERT_E_UNTRUSTEDROOT = 0x800B0109
+	CERT_E_CN_NO_MATCH   = 0x800B010F
+
+	AUTHTYPE_CLIENT = 1
+	AUTHTYPE_SERVER = 2
+)
+
+var (
+	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
+	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
+	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
+)
+
+// Invented values to support what package os expects.
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+func (tv *Timeval) Nanoseconds() int64 {
+	return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	tv.Sec = int32(nsec / 1e9)
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	return
+}
+
+type SecurityAttributes struct {
+	Length             uint32
+	SecurityDescriptor uintptr
+	InheritHandle      uint32
+}
+
+type Overlapped struct {
+	Internal     uintptr
+	InternalHigh uintptr
+	Offset       uint32
+	OffsetHigh   uint32
+	HEvent       Handle
+}
+
+type FileNotifyInformation struct {
+	NextEntryOffset uint32
+	Action          uint32
+	FileNameLength  uint32
+	FileName        uint16
+}
+
+type Filetime struct {
+	LowDateTime  uint32
+	HighDateTime uint32
+}
+
+// Nanoseconds returns Filetime ft in nanoseconds
+// since Epoch (00:00:00 UTC, January 1, 1970).
+func (ft *Filetime) Nanoseconds() int64 {
+	// 100-nanosecond intervals since January 1, 1601
+	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
+	// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
+	nsec -= 116444736000000000
+	// convert into nanoseconds
+	nsec *= 100
+	return nsec
+}
+
+func NsecToFiletime(nsec int64) (ft Filetime) {
+	// convert into 100-nanosecond
+	nsec /= 100
+	// change starting time to January 1, 1601
+	nsec += 116444736000000000
+	// split into high / low
+	ft.LowDateTime = uint32(nsec & 0xffffffff)
+	ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
+	return ft
+}
+
+type Win32finddata struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH - 1]uint16
+	AlternateFileName [13]uint16
+}
+
+// This is the actual system call structure.
+// Win32finddata is what we committed to in Go 1.
+type win32finddata1 struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH]uint16
+	AlternateFileName [14]uint16
+}
+
+func copyFindData(dst *Win32finddata, src *win32finddata1) {
+	dst.FileAttributes = src.FileAttributes
+	dst.CreationTime = src.CreationTime
+	dst.LastAccessTime = src.LastAccessTime
+	dst.LastWriteTime = src.LastWriteTime
+	dst.FileSizeHigh = src.FileSizeHigh
+	dst.FileSizeLow = src.FileSizeLow
+	dst.Reserved0 = src.Reserved0
+	dst.Reserved1 = src.Reserved1
+
+	// The src is 1 element bigger than dst, but it must be NUL.
+	copy(dst.FileName[:], src.FileName[:])
+	copy(dst.AlternateFileName[:], src.AlternateFileName[:])
+}
+
+type ByHandleFileInformation struct {
+	FileAttributes     uint32
+	CreationTime       Filetime
+	LastAccessTime     Filetime
+	LastWriteTime      Filetime
+	VolumeSerialNumber uint32
+	FileSizeHigh       uint32
+	FileSizeLow        uint32
+	NumberOfLinks      uint32
+	FileIndexHigh      uint32
+	FileIndexLow       uint32
+}
+
+const (
+	GetFileExInfoStandard = 0
+	GetFileExMaxInfoLevel = 1
+)
+
+type Win32FileAttributeData struct {
+	FileAttributes uint32
+	CreationTime   Filetime
+	LastAccessTime Filetime
+	LastWriteTime  Filetime
+	FileSizeHigh   uint32
+	FileSizeLow    uint32
+}
+
+// ShowWindow constants
+const (
+	// winuser.h
+	SW_HIDE            = 0
+	SW_NORMAL          = 1
+	SW_SHOWNORMAL      = 1
+	SW_SHOWMINIMIZED   = 2
+	SW_SHOWMAXIMIZED   = 3
+	SW_MAXIMIZE        = 3
+	SW_SHOWNOACTIVATE  = 4
+	SW_SHOW            = 5
+	SW_MINIMIZE        = 6
+	SW_SHOWMINNOACTIVE = 7
+	SW_SHOWNA          = 8
+	SW_RESTORE         = 9
+	SW_SHOWDEFAULT     = 10
+	SW_FORCEMINIMIZE   = 11
+)
+
+type StartupInfo struct {
+	Cb            uint32
+	_             *uint16
+	Desktop       *uint16
+	Title         *uint16
+	X             uint32
+	Y             uint32
+	XSize         uint32
+	YSize         uint32
+	XCountChars   uint32
+	YCountChars   uint32
+	FillAttribute uint32
+	Flags         uint32
+	ShowWindow    uint16
+	_             uint16
+	_             *byte
+	StdInput      Handle
+	StdOutput     Handle
+	StdErr        Handle
+}
+
+type ProcessInformation struct {
+	Process   Handle
+	Thread    Handle
+	ProcessId uint32
+	ThreadId  uint32
+}
+
+type ProcessEntry32 struct {
+	Size            uint32
+	Usage           uint32
+	ProcessID       uint32
+	DefaultHeapID   uintptr
+	ModuleID        uint32
+	Threads         uint32
+	ParentProcessID uint32
+	PriClassBase    int32
+	Flags           uint32
+	ExeFile         [MAX_PATH]uint16
+}
+
+type Systemtime struct {
+	Year         uint16
+	Month        uint16
+	DayOfWeek    uint16
+	Day          uint16
+	Hour         uint16
+	Minute       uint16
+	Second       uint16
+	Milliseconds uint16
+}
+
+type Timezoneinformation struct {
+	Bias         int32
+	StandardName [32]uint16
+	StandardDate Systemtime
+	StandardBias int32
+	DaylightName [32]uint16
+	DaylightDate Systemtime
+	DaylightBias int32
+}
+
+// Socket related.
+
+const (
+	AF_UNSPEC  = 0
+	AF_UNIX    = 1
+	AF_INET    = 2
+	AF_INET6   = 23
+	AF_NETBIOS = 17
+
+	SOCK_STREAM    = 1
+	SOCK_DGRAM     = 2
+	SOCK_RAW       = 3
+	SOCK_SEQPACKET = 5
+
+	IPPROTO_IP   = 0
+	IPPROTO_IPV6 = 0x29
+	IPPROTO_TCP  = 6
+	IPPROTO_UDP  = 17
+
+	SOL_SOCKET                = 0xffff
+	SO_REUSEADDR              = 4
+	SO_KEEPALIVE              = 8
+	SO_DONTROUTE              = 16
+	SO_BROADCAST              = 32
+	SO_LINGER                 = 128
+	SO_RCVBUF                 = 0x1002
+	SO_SNDBUF                 = 0x1001
+	SO_UPDATE_ACCEPT_CONTEXT  = 0x700b
+	SO_UPDATE_CONNECT_CONTEXT = 0x7010
+
+	IOC_OUT                            = 0x40000000
+	IOC_IN                             = 0x80000000
+	IOC_VENDOR                         = 0x18000000
+	IOC_INOUT                          = IOC_IN | IOC_OUT
+	IOC_WS2                            = 0x08000000
+	SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
+	SIO_KEEPALIVE_VALS                 = IOC_IN | IOC_VENDOR | 4
+	SIO_UDP_CONNRESET                  = IOC_IN | IOC_VENDOR | 12
+
+	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
+
+	IP_TOS             = 0x3
+	IP_TTL             = 0x4
+	IP_MULTICAST_IF    = 0x9
+	IP_MULTICAST_TTL   = 0xa
+	IP_MULTICAST_LOOP  = 0xb
+	IP_ADD_MEMBERSHIP  = 0xc
+	IP_DROP_MEMBERSHIP = 0xd
+
+	IPV6_V6ONLY         = 0x1b
+	IPV6_UNICAST_HOPS   = 0x4
+	IPV6_MULTICAST_IF   = 0x9
+	IPV6_MULTICAST_HOPS = 0xa
+	IPV6_MULTICAST_LOOP = 0xb
+	IPV6_JOIN_GROUP     = 0xc
+	IPV6_LEAVE_GROUP    = 0xd
+
+	MSG_OOB       = 0x1
+	MSG_PEEK      = 0x2
+	MSG_DONTROUTE = 0x4
+	MSG_WAITALL   = 0x8
+
+	MSG_TRUNC  = 0x0100
+	MSG_CTRUNC = 0x0200
+	MSG_BCAST  = 0x0400
+	MSG_MCAST  = 0x0800
+
+	SOMAXCONN = 0x7fffffff
+
+	TCP_NODELAY = 1
+
+	SHUT_RD   = 0
+	SHUT_WR   = 1
+	SHUT_RDWR = 2
+
+	WSADESCRIPTION_LEN = 256
+	WSASYS_STATUS_LEN  = 128
+)
+
+type WSABuf struct {
+	Len uint32
+	Buf *byte
+}
+
+type WSAMsg struct {
+	Name        *syscall.RawSockaddrAny
+	Namelen     int32
+	Buffers     *WSABuf
+	BufferCount uint32
+	Control     WSABuf
+	Flags       uint32
+}
+
+// Invented values to support what package os expects.
+const (
+	S_IFMT   = 0x1f000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+	S_ISUID  = 0x800
+	S_ISGID  = 0x400
+	S_ISVTX  = 0x200
+	S_IRUSR  = 0x100
+	S_IWRITE = 0x80
+	S_IWUSR  = 0x80
+	S_IXUSR  = 0x40
+)
+
+const (
+	FILE_TYPE_CHAR    = 0x0002
+	FILE_TYPE_DISK    = 0x0001
+	FILE_TYPE_PIPE    = 0x0003
+	FILE_TYPE_REMOTE  = 0x8000
+	FILE_TYPE_UNKNOWN = 0x0000
+)
+
+type Hostent struct {
+	Name     *byte
+	Aliases  **byte
+	AddrType uint16
+	Length   uint16
+	AddrList **byte
+}
+
+type Protoent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   uint16
+}
+
+const (
+	DNS_TYPE_A       = 0x0001
+	DNS_TYPE_NS      = 0x0002
+	DNS_TYPE_MD      = 0x0003
+	DNS_TYPE_MF      = 0x0004
+	DNS_TYPE_CNAME   = 0x0005
+	DNS_TYPE_SOA     = 0x0006
+	DNS_TYPE_MB      = 0x0007
+	DNS_TYPE_MG      = 0x0008
+	DNS_TYPE_MR      = 0x0009
+	DNS_TYPE_NULL    = 0x000a
+	DNS_TYPE_WKS     = 0x000b
+	DNS_TYPE_PTR     = 0x000c
+	DNS_TYPE_HINFO   = 0x000d
+	DNS_TYPE_MINFO   = 0x000e
+	DNS_TYPE_MX      = 0x000f
+	DNS_TYPE_TEXT    = 0x0010
+	DNS_TYPE_RP      = 0x0011
+	DNS_TYPE_AFSDB   = 0x0012
+	DNS_TYPE_X25     = 0x0013
+	DNS_TYPE_ISDN    = 0x0014
+	DNS_TYPE_RT      = 0x0015
+	DNS_TYPE_NSAP    = 0x0016
+	DNS_TYPE_NSAPPTR = 0x0017
+	DNS_TYPE_SIG     = 0x0018
+	DNS_TYPE_KEY     = 0x0019
+	DNS_TYPE_PX      = 0x001a
+	DNS_TYPE_GPOS    = 0x001b
+	DNS_TYPE_AAAA    = 0x001c
+	DNS_TYPE_LOC     = 0x001d
+	DNS_TYPE_NXT     = 0x001e
+	DNS_TYPE_EID     = 0x001f
+	DNS_TYPE_NIMLOC  = 0x0020
+	DNS_TYPE_SRV     = 0x0021
+	DNS_TYPE_ATMA    = 0x0022
+	DNS_TYPE_NAPTR   = 0x0023
+	DNS_TYPE_KX      = 0x0024
+	DNS_TYPE_CERT    = 0x0025
+	DNS_TYPE_A6      = 0x0026
+	DNS_TYPE_DNAME   = 0x0027
+	DNS_TYPE_SINK    = 0x0028
+	DNS_TYPE_OPT     = 0x0029
+	DNS_TYPE_DS      = 0x002B
+	DNS_TYPE_RRSIG   = 0x002E
+	DNS_TYPE_NSEC    = 0x002F
+	DNS_TYPE_DNSKEY  = 0x0030
+	DNS_TYPE_DHCID   = 0x0031
+	DNS_TYPE_UINFO   = 0x0064
+	DNS_TYPE_UID     = 0x0065
+	DNS_TYPE_GID     = 0x0066
+	DNS_TYPE_UNSPEC  = 0x0067
+	DNS_TYPE_ADDRS   = 0x00f8
+	DNS_TYPE_TKEY    = 0x00f9
+	DNS_TYPE_TSIG    = 0x00fa
+	DNS_TYPE_IXFR    = 0x00fb
+	DNS_TYPE_AXFR    = 0x00fc
+	DNS_TYPE_MAILB   = 0x00fd
+	DNS_TYPE_MAILA   = 0x00fe
+	DNS_TYPE_ALL     = 0x00ff
+	DNS_TYPE_ANY     = 0x00ff
+	DNS_TYPE_WINS    = 0xff01
+	DNS_TYPE_WINSR   = 0xff02
+	DNS_TYPE_NBSTAT  = 0xff01
+)
+
+const (
+	DNS_INFO_NO_RECORDS = 0x251D
+)
+
+const (
+	// flags inside DNSRecord.Dw
+	DnsSectionQuestion   = 0x0000
+	DnsSectionAnswer     = 0x0001
+	DnsSectionAuthority  = 0x0002
+	DnsSectionAdditional = 0x0003
+)
+
+type DNSSRVData struct {
+	Target   *uint16
+	Priority uint16
+	Weight   uint16
+	Port     uint16
+	Pad      uint16
+}
+
+type DNSPTRData struct {
+	Host *uint16
+}
+
+type DNSMXData struct {
+	NameExchange *uint16
+	Preference   uint16
+	Pad          uint16
+}
+
+type DNSTXTData struct {
+	StringCount uint16
+	StringArray [1]*uint16
+}
+
+type DNSRecord struct {
+	Next     *DNSRecord
+	Name     *uint16
+	Type     uint16
+	Length   uint16
+	Dw       uint32
+	Ttl      uint32
+	Reserved uint32
+	Data     [40]byte
+}
+
+const (
+	TF_DISCONNECT         = 1
+	TF_REUSE_SOCKET       = 2
+	TF_WRITE_BEHIND       = 4
+	TF_USE_DEFAULT_WORKER = 0
+	TF_USE_SYSTEM_THREAD  = 16
+	TF_USE_KERNEL_APC     = 32
+)
+
+type TransmitFileBuffers struct {
+	Head       uintptr
+	HeadLength uint32
+	Tail       uintptr
+	TailLength uint32
+}
+
+const (
+	IFF_UP           = 1
+	IFF_BROADCAST    = 2
+	IFF_LOOPBACK     = 4
+	IFF_POINTTOPOINT = 8
+	IFF_MULTICAST    = 16
+)
+
+const SIO_GET_INTERFACE_LIST = 0x4004747F
+
+// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old.
+// will be fixed to change variable type as suitable.
+
+type SockaddrGen [24]byte
+
+type InterfaceInfo struct {
+	Flags            uint32
+	Address          SockaddrGen
+	BroadcastAddress SockaddrGen
+	Netmask          SockaddrGen
+}
+
+type IpAddressString struct {
+	String [16]byte
+}
+
+type IpMaskString IpAddressString
+
+type IpAddrString struct {
+	Next      *IpAddrString
+	IpAddress IpAddressString
+	IpMask    IpMaskString
+	Context   uint32
+}
+
+const MAX_ADAPTER_NAME_LENGTH = 256
+const MAX_ADAPTER_DESCRIPTION_LENGTH = 128
+const MAX_ADAPTER_ADDRESS_LENGTH = 8
+
+type IpAdapterInfo struct {
+	Next                *IpAdapterInfo
+	ComboIndex          uint32
+	AdapterName         [MAX_ADAPTER_NAME_LENGTH + 4]byte
+	Description         [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte
+	AddressLength       uint32
+	Address             [MAX_ADAPTER_ADDRESS_LENGTH]byte
+	Index               uint32
+	Type                uint32
+	DhcpEnabled         uint32
+	CurrentIpAddress    *IpAddrString
+	IpAddressList       IpAddrString
+	GatewayList         IpAddrString
+	DhcpServer          IpAddrString
+	HaveWins            bool
+	PrimaryWinsServer   IpAddrString
+	SecondaryWinsServer IpAddrString
+	LeaseObtained       int64
+	LeaseExpires        int64
+}
+
+const MAXLEN_PHYSADDR = 8
+const MAX_INTERFACE_NAME_LEN = 256
+const MAXLEN_IFDESCR = 256
+
+type MibIfRow struct {
+	Name            [MAX_INTERFACE_NAME_LEN]uint16
+	Index           uint32
+	Type            uint32
+	Mtu             uint32
+	Speed           uint32
+	PhysAddrLen     uint32
+	PhysAddr        [MAXLEN_PHYSADDR]byte
+	AdminStatus     uint32
+	OperStatus      uint32
+	LastChange      uint32
+	InOctets        uint32
+	InUcastPkts     uint32
+	InNUcastPkts    uint32
+	InDiscards      uint32
+	InErrors        uint32
+	InUnknownProtos uint32
+	OutOctets       uint32
+	OutUcastPkts    uint32
+	OutNUcastPkts   uint32
+	OutDiscards     uint32
+	OutErrors       uint32
+	OutQLen         uint32
+	DescrLen        uint32
+	Descr           [MAXLEN_IFDESCR]byte
+}
+
+type CertContext struct {
+	EncodingType uint32
+	EncodedCert  *byte
+	Length       uint32
+	CertInfo     uintptr
+	Store        Handle
+}
+
+type CertChainContext struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	ChainCount                 uint32
+	Chains                     **CertSimpleChain
+	LowerQualityChainCount     uint32
+	LowerQualityChains         **CertChainContext
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertSimpleChain struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	NumElements                uint32
+	Elements                   **CertChainElement
+	TrustListInfo              uintptr
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertChainElement struct {
+	Size              uint32
+	CertContext       *CertContext
+	TrustStatus       CertTrustStatus
+	RevocationInfo    *CertRevocationInfo
+	IssuanceUsage     *CertEnhKeyUsage
+	ApplicationUsage  *CertEnhKeyUsage
+	ExtendedErrorInfo *uint16
+}
+
+type CertRevocationInfo struct {
+	Size             uint32
+	RevocationResult uint32
+	RevocationOid    *byte
+	OidSpecificInfo  uintptr
+	HasFreshnessTime uint32
+	FreshnessTime    uint32
+	CrlInfo          uintptr // *CertRevocationCrlInfo
+}
+
+type CertTrustStatus struct {
+	ErrorStatus uint32
+	InfoStatus  uint32
+}
+
+type CertUsageMatch struct {
+	Type  uint32
+	Usage CertEnhKeyUsage
+}
+
+type CertEnhKeyUsage struct {
+	Length           uint32
+	UsageIdentifiers **byte
+}
+
+type CertChainPara struct {
+	Size                         uint32
+	RequestedUsage               CertUsageMatch
+	RequstedIssuancePolicy       CertUsageMatch
+	URLRetrievalTimeout          uint32
+	CheckRevocationFreshnessTime uint32
+	RevocationFreshnessTime      uint32
+	CacheResync                  *Filetime
+}
+
+type CertChainPolicyPara struct {
+	Size            uint32
+	Flags           uint32
+	ExtraPolicyPara uintptr
+}
+
+type SSLExtraCertChainPolicyPara struct {
+	Size       uint32
+	AuthType   uint32
+	Checks     uint32
+	ServerName *uint16
+}
+
+type CertChainPolicyStatus struct {
+	Size              uint32
+	Error             uint32
+	ChainIndex        uint32
+	ElementIndex      uint32
+	ExtraPolicyStatus uintptr
+}
+
+const (
+	// do not reorder
+	HKEY_CLASSES_ROOT = 0x80000000 + iota
+	HKEY_CURRENT_USER
+	HKEY_LOCAL_MACHINE
+	HKEY_USERS
+	HKEY_PERFORMANCE_DATA
+	HKEY_CURRENT_CONFIG
+	HKEY_DYN_DATA
+
+	KEY_QUERY_VALUE        = 1
+	KEY_SET_VALUE          = 2
+	KEY_CREATE_SUB_KEY     = 4
+	KEY_ENUMERATE_SUB_KEYS = 8
+	KEY_NOTIFY             = 16
+	KEY_CREATE_LINK        = 32
+	KEY_WRITE              = 0x20006
+	KEY_EXECUTE            = 0x20019
+	KEY_READ               = 0x20019
+	KEY_WOW64_64KEY        = 0x0100
+	KEY_WOW64_32KEY        = 0x0200
+	KEY_ALL_ACCESS         = 0xf003f
+)
+
+const (
+	// do not reorder
+	REG_NONE = iota
+	REG_SZ
+	REG_EXPAND_SZ
+	REG_BINARY
+	REG_DWORD_LITTLE_ENDIAN
+	REG_DWORD_BIG_ENDIAN
+	REG_LINK
+	REG_MULTI_SZ
+	REG_RESOURCE_LIST
+	REG_FULL_RESOURCE_DESCRIPTOR
+	REG_RESOURCE_REQUIREMENTS_LIST
+	REG_QWORD_LITTLE_ENDIAN
+	REG_DWORD = REG_DWORD_LITTLE_ENDIAN
+	REG_QWORD = REG_QWORD_LITTLE_ENDIAN
+)
+
+type AddrinfoW struct {
+	Flags     int32
+	Family    int32
+	Socktype  int32
+	Protocol  int32
+	Addrlen   uintptr
+	Canonname *uint16
+	Addr      uintptr
+	Next      *AddrinfoW
+}
+
+const (
+	AI_PASSIVE     = 1
+	AI_CANONNAME   = 2
+	AI_NUMERICHOST = 4
+)
+
+type GUID struct {
+	Data1 uint32
+	Data2 uint16
+	Data3 uint16
+	Data4 [8]byte
+}
+
+var WSAID_CONNECTEX = GUID{
+	0x25a207b9,
+	0xddf3,
+	0x4660,
+	[8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
+}
+
+var WSAID_WSASENDMSG = GUID{
+	0xa441e712,
+	0x754f,
+	0x43ca,
+	[8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
+}
+
+var WSAID_WSARECVMSG = GUID{
+	0xf689d7c8,
+	0x6f1f,
+	0x436b,
+	[8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
+}
+
+const (
+	FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
+	FILE_SKIP_SET_EVENT_ON_HANDLE        = 2
+)
+
+const (
+	WSAPROTOCOL_LEN    = 255
+	MAX_PROTOCOL_CHAIN = 7
+	BASE_PROTOCOL      = 1
+	LAYERED_PROTOCOL   = 0
+
+	XP1_CONNECTIONLESS           = 0x00000001
+	XP1_GUARANTEED_DELIVERY      = 0x00000002
+	XP1_GUARANTEED_ORDER         = 0x00000004
+	XP1_MESSAGE_ORIENTED         = 0x00000008
+	XP1_PSEUDO_STREAM            = 0x00000010
+	XP1_GRACEFUL_CLOSE           = 0x00000020
+	XP1_EXPEDITED_DATA           = 0x00000040
+	XP1_CONNECT_DATA             = 0x00000080
+	XP1_DISCONNECT_DATA          = 0x00000100
+	XP1_SUPPORT_BROADCAST        = 0x00000200
+	XP1_SUPPORT_MULTIPOINT       = 0x00000400
+	XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800
+	XP1_MULTIPOINT_DATA_PLANE    = 0x00001000
+	XP1_QOS_SUPPORTED            = 0x00002000
+	XP1_UNI_SEND                 = 0x00008000
+	XP1_UNI_RECV                 = 0x00010000
+	XP1_IFS_HANDLES              = 0x00020000
+	XP1_PARTIAL_MESSAGE          = 0x00040000
+	XP1_SAN_SUPPORT_SDP          = 0x00080000
+
+	PFL_MULTIPLE_PROTO_ENTRIES  = 0x00000001
+	PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002
+	PFL_HIDDEN                  = 0x00000004
+	PFL_MATCHES_PROTOCOL_ZERO   = 0x00000008
+	PFL_NETWORKDIRECT_PROVIDER  = 0x00000010
+)
+
+type WSAProtocolInfo struct {
+	ServiceFlags1     uint32
+	ServiceFlags2     uint32
+	ServiceFlags3     uint32
+	ServiceFlags4     uint32
+	ProviderFlags     uint32
+	ProviderId        GUID
+	CatalogEntryId    uint32
+	ProtocolChain     WSAProtocolChain
+	Version           int32
+	AddressFamily     int32
+	MaxSockAddr       int32
+	MinSockAddr       int32
+	SocketType        int32
+	Protocol          int32
+	ProtocolMaxOffset int32
+	NetworkByteOrder  int32
+	SecurityScheme    int32
+	MessageSize       uint32
+	ProviderReserved  uint32
+	ProtocolName      [WSAPROTOCOL_LEN + 1]uint16
+}
+
+type WSAProtocolChain struct {
+	ChainLen     int32
+	ChainEntries [MAX_PROTOCOL_CHAIN]uint32
+}
+
+type TCPKeepalive struct {
+	OnOff    uint32
+	Time     uint32
+	Interval uint32
+}
+
+type symbolicLinkReparseBuffer struct {
+	SubstituteNameOffset uint16
+	SubstituteNameLength uint16
+	PrintNameOffset      uint16
+	PrintNameLength      uint16
+	Flags                uint32
+	PathBuffer           [1]uint16
+}
+
+type mountPointReparseBuffer struct {
+	SubstituteNameOffset uint16
+	SubstituteNameLength uint16
+	PrintNameOffset      uint16
+	PrintNameLength      uint16
+	PathBuffer           [1]uint16
+}
+
+type reparseDataBuffer struct {
+	ReparseTag        uint32
+	ReparseDataLength uint16
+	Reserved          uint16
+
+	// GenericReparseBuffer
+	reparseBuffer byte
+}
+
+const (
+	FSCTL_GET_REPARSE_POINT          = 0x900A8
+	MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
+	IO_REPARSE_TAG_MOUNT_POINT       = 0xA0000003
+	IO_REPARSE_TAG_SYMLINK           = 0xA000000C
+	SYMBOLIC_LINK_FLAG_DIRECTORY     = 0x1
+)
+
+const (
+	ComputerNameNetBIOS                   = 0
+	ComputerNameDnsHostname               = 1
+	ComputerNameDnsDomain                 = 2
+	ComputerNameDnsFullyQualified         = 3
+	ComputerNamePhysicalNetBIOS           = 4
+	ComputerNamePhysicalDnsHostname       = 5
+	ComputerNamePhysicalDnsDomain         = 6
+	ComputerNamePhysicalDnsFullyQualified = 7
+	ComputerNameMax                       = 8
+)
+
+const (
+	MOVEFILE_REPLACE_EXISTING      = 0x1
+	MOVEFILE_COPY_ALLOWED          = 0x2
+	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
+	MOVEFILE_WRITE_THROUGH         = 0x8
+	MOVEFILE_CREATE_HARDLINK       = 0x10
+	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
+)
+
+const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
+
+const (
+	IF_TYPE_OTHER              = 1
+	IF_TYPE_ETHERNET_CSMACD    = 6
+	IF_TYPE_ISO88025_TOKENRING = 9
+	IF_TYPE_PPP                = 23
+	IF_TYPE_SOFTWARE_LOOPBACK  = 24
+	IF_TYPE_ATM                = 37
+	IF_TYPE_IEEE80211          = 71
+	IF_TYPE_TUNNEL             = 131
+	IF_TYPE_IEEE1394           = 144
+)
+
+type SocketAddress struct {
+	Sockaddr       *syscall.RawSockaddrAny
+	SockaddrLength int32
+}
+
+type IpAdapterUnicastAddress struct {
+	Length             uint32
+	Flags              uint32
+	Next               *IpAdapterUnicastAddress
+	Address            SocketAddress
+	PrefixOrigin       int32
+	SuffixOrigin       int32
+	DadState           int32
+	ValidLifetime      uint32
+	PreferredLifetime  uint32
+	LeaseLifetime      uint32
+	OnLinkPrefixLength uint8
+}
+
+type IpAdapterAnycastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterAnycastAddress
+	Address SocketAddress
+}
+
+type IpAdapterMulticastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterMulticastAddress
+	Address SocketAddress
+}
+
+type IpAdapterDnsServerAdapter struct {
+	Length   uint32
+	Reserved uint32
+	Next     *IpAdapterDnsServerAdapter
+	Address  SocketAddress
+}
+
+type IpAdapterPrefix struct {
+	Length       uint32
+	Flags        uint32
+	Next         *IpAdapterPrefix
+	Address      SocketAddress
+	PrefixLength uint32
+}
+
+type IpAdapterAddresses struct {
+	Length                uint32
+	IfIndex               uint32
+	Next                  *IpAdapterAddresses
+	AdapterName           *byte
+	FirstUnicastAddress   *IpAdapterUnicastAddress
+	FirstAnycastAddress   *IpAdapterAnycastAddress
+	FirstMulticastAddress *IpAdapterMulticastAddress
+	FirstDnsServerAddress *IpAdapterDnsServerAdapter
+	DnsSuffix             *uint16
+	Description           *uint16
+	FriendlyName          *uint16
+	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
+	PhysicalAddressLength uint32
+	Flags                 uint32
+	Mtu                   uint32
+	IfType                uint32
+	OperStatus            uint32
+	Ipv6IfIndex           uint32
+	ZoneIndices           [16]uint32
+	FirstPrefix           *IpAdapterPrefix
+	/* more fields might be present here. */
+}
+
+const (
+	IfOperStatusUp             = 1
+	IfOperStatusDown           = 2
+	IfOperStatusTesting        = 3
+	IfOperStatusUnknown        = 4
+	IfOperStatusDormant        = 5
+	IfOperStatusNotPresent     = 6
+	IfOperStatusLowerLayerDown = 7
+)
+
+// Console related constants used for the mode parameter to SetConsoleMode. See
+// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
+
+const (
+	ENABLE_PROCESSED_INPUT        = 0x1
+	ENABLE_LINE_INPUT             = 0x2
+	ENABLE_ECHO_INPUT             = 0x4
+	ENABLE_WINDOW_INPUT           = 0x8
+	ENABLE_MOUSE_INPUT            = 0x10
+	ENABLE_INSERT_MODE            = 0x20
+	ENABLE_QUICK_EDIT_MODE        = 0x40
+	ENABLE_EXTENDED_FLAGS         = 0x80
+	ENABLE_AUTO_POSITION          = 0x100
+	ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200
+
+	ENABLE_PROCESSED_OUTPUT            = 0x1
+	ENABLE_WRAP_AT_EOL_OUTPUT          = 0x2
+	ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4
+	DISABLE_NEWLINE_AUTO_RETURN        = 0x8
+	ENABLE_LVB_GRID_WORLDWIDE          = 0x10
+)
+
+type Coord struct {
+	X int16
+	Y int16
+}
+
+type SmallRect struct {
+	Left   int16
+	Top    int16
+	Right  int16
+	Bottom int16
+}
+
+// Used with GetConsoleScreenBuffer to retreive information about a console
+// screen buffer. See
+// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
+// for details.
+
+type ConsoleScreenBufferInfo struct {
+	Size              Coord
+	CursorPosition    Coord
+	Attributes        uint16
+	Window            SmallRect
+	MaximumWindowSize Coord
+}
diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe0ddd0316019285881af8d34dcda8138f9c86d4
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/types_windows_386.go
@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Port    uint16
+	Proto   *byte
+}
diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go
new file mode 100644
index 0000000000000000000000000000000000000000..7e154c2df2df6cc56597e45cceec0d84ac975980
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/types_windows_amd64.go
@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   *byte
+	Port    uint16
+}
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7b3b15eadb9211c1c1d9067293e4d14426c6cf0
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -0,0 +1,2687 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package windows
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modadvapi32 = NewLazySystemDLL("advapi32.dll")
+	modkernel32 = NewLazySystemDLL("kernel32.dll")
+	modshell32  = NewLazySystemDLL("shell32.dll")
+	modmswsock  = NewLazySystemDLL("mswsock.dll")
+	modcrypt32  = NewLazySystemDLL("crypt32.dll")
+	modws2_32   = NewLazySystemDLL("ws2_32.dll")
+	moddnsapi   = NewLazySystemDLL("dnsapi.dll")
+	modiphlpapi = NewLazySystemDLL("iphlpapi.dll")
+	modsecur32  = NewLazySystemDLL("secur32.dll")
+	modnetapi32 = NewLazySystemDLL("netapi32.dll")
+	moduserenv  = NewLazySystemDLL("userenv.dll")
+
+	procRegisterEventSourceW               = modadvapi32.NewProc("RegisterEventSourceW")
+	procDeregisterEventSource              = modadvapi32.NewProc("DeregisterEventSource")
+	procReportEventW                       = modadvapi32.NewProc("ReportEventW")
+	procOpenSCManagerW                     = modadvapi32.NewProc("OpenSCManagerW")
+	procCloseServiceHandle                 = modadvapi32.NewProc("CloseServiceHandle")
+	procCreateServiceW                     = modadvapi32.NewProc("CreateServiceW")
+	procOpenServiceW                       = modadvapi32.NewProc("OpenServiceW")
+	procDeleteService                      = modadvapi32.NewProc("DeleteService")
+	procStartServiceW                      = modadvapi32.NewProc("StartServiceW")
+	procQueryServiceStatus                 = modadvapi32.NewProc("QueryServiceStatus")
+	procControlService                     = modadvapi32.NewProc("ControlService")
+	procStartServiceCtrlDispatcherW        = modadvapi32.NewProc("StartServiceCtrlDispatcherW")
+	procSetServiceStatus                   = modadvapi32.NewProc("SetServiceStatus")
+	procChangeServiceConfigW               = modadvapi32.NewProc("ChangeServiceConfigW")
+	procQueryServiceConfigW                = modadvapi32.NewProc("QueryServiceConfigW")
+	procChangeServiceConfig2W              = modadvapi32.NewProc("ChangeServiceConfig2W")
+	procQueryServiceConfig2W               = modadvapi32.NewProc("QueryServiceConfig2W")
+	procEnumServicesStatusExW              = modadvapi32.NewProc("EnumServicesStatusExW")
+	procGetLastError                       = modkernel32.NewProc("GetLastError")
+	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
+	procLoadLibraryExW                     = modkernel32.NewProc("LoadLibraryExW")
+	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
+	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
+	procGetVersion                         = modkernel32.NewProc("GetVersion")
+	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
+	procExitProcess                        = modkernel32.NewProc("ExitProcess")
+	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
+	procReadFile                           = modkernel32.NewProc("ReadFile")
+	procWriteFile                          = modkernel32.NewProc("WriteFile")
+	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
+	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
+	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
+	procSetStdHandle                       = modkernel32.NewProc("SetStdHandle")
+	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
+	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
+	procFindClose                          = modkernel32.NewProc("FindClose")
+	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
+	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
+	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
+	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
+	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
+	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
+	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
+	procMoveFileExW                        = modkernel32.NewProc("MoveFileExW")
+	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
+	procGetComputerNameExW                 = modkernel32.NewProc("GetComputerNameExW")
+	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
+	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
+	procGetSystemTimePreciseAsFileTime     = modkernel32.NewProc("GetSystemTimePreciseAsFileTime")
+	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
+	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
+	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
+	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
+	procCancelIo                           = modkernel32.NewProc("CancelIo")
+	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
+	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
+	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
+	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
+	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
+	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
+	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
+	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
+	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
+	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
+	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
+	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
+	procGetFileType                        = modkernel32.NewProc("GetFileType")
+	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
+	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
+	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
+	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
+	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
+	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
+	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
+	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
+	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
+	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
+	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
+	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
+	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
+	procLocalFree                          = modkernel32.NewProc("LocalFree")
+	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
+	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
+	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
+	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
+	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
+	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
+	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
+	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
+	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
+	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
+	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
+	procVirtualAlloc                       = modkernel32.NewProc("VirtualAlloc")
+	procVirtualFree                        = modkernel32.NewProc("VirtualFree")
+	procVirtualProtect                     = modkernel32.NewProc("VirtualProtect")
+	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
+	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
+	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
+	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
+	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
+	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
+	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
+	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
+	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
+	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
+	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
+	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
+	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
+	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
+	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
+	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
+	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
+	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
+	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
+	procSetConsoleMode                     = modkernel32.NewProc("SetConsoleMode")
+	procGetConsoleScreenBufferInfo         = modkernel32.NewProc("GetConsoleScreenBufferInfo")
+	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
+	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
+	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
+	procProcess32FirstW                    = modkernel32.NewProc("Process32FirstW")
+	procProcess32NextW                     = modkernel32.NewProc("Process32NextW")
+	procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
+	procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
+	procCreateHardLinkW                    = modkernel32.NewProc("CreateHardLinkW")
+	procGetCurrentThreadId                 = modkernel32.NewProc("GetCurrentThreadId")
+	procCreateEventW                       = modkernel32.NewProc("CreateEventW")
+	procCreateEventExW                     = modkernel32.NewProc("CreateEventExW")
+	procOpenEventW                         = modkernel32.NewProc("OpenEventW")
+	procSetEvent                           = modkernel32.NewProc("SetEvent")
+	procResetEvent                         = modkernel32.NewProc("ResetEvent")
+	procPulseEvent                         = modkernel32.NewProc("PulseEvent")
+	procDefineDosDeviceW                   = modkernel32.NewProc("DefineDosDeviceW")
+	procDeleteVolumeMountPointW            = modkernel32.NewProc("DeleteVolumeMountPointW")
+	procFindFirstVolumeW                   = modkernel32.NewProc("FindFirstVolumeW")
+	procFindFirstVolumeMountPointW         = modkernel32.NewProc("FindFirstVolumeMountPointW")
+	procFindNextVolumeW                    = modkernel32.NewProc("FindNextVolumeW")
+	procFindNextVolumeMountPointW          = modkernel32.NewProc("FindNextVolumeMountPointW")
+	procFindVolumeClose                    = modkernel32.NewProc("FindVolumeClose")
+	procFindVolumeMountPointClose          = modkernel32.NewProc("FindVolumeMountPointClose")
+	procGetDriveTypeW                      = modkernel32.NewProc("GetDriveTypeW")
+	procGetLogicalDrives                   = modkernel32.NewProc("GetLogicalDrives")
+	procGetLogicalDriveStringsW            = modkernel32.NewProc("GetLogicalDriveStringsW")
+	procGetVolumeInformationW              = modkernel32.NewProc("GetVolumeInformationW")
+	procGetVolumeInformationByHandleW      = modkernel32.NewProc("GetVolumeInformationByHandleW")
+	procGetVolumeNameForVolumeMountPointW  = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW")
+	procGetVolumePathNameW                 = modkernel32.NewProc("GetVolumePathNameW")
+	procGetVolumePathNamesForVolumeNameW   = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
+	procQueryDosDeviceW                    = modkernel32.NewProc("QueryDosDeviceW")
+	procSetVolumeLabelW                    = modkernel32.NewProc("SetVolumeLabelW")
+	procSetVolumeMountPointW               = modkernel32.NewProc("SetVolumeMountPointW")
+	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
+	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
+	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
+	procsocket                             = modws2_32.NewProc("socket")
+	procsetsockopt                         = modws2_32.NewProc("setsockopt")
+	procgetsockopt                         = modws2_32.NewProc("getsockopt")
+	procbind                               = modws2_32.NewProc("bind")
+	procconnect                            = modws2_32.NewProc("connect")
+	procgetsockname                        = modws2_32.NewProc("getsockname")
+	procgetpeername                        = modws2_32.NewProc("getpeername")
+	proclisten                             = modws2_32.NewProc("listen")
+	procshutdown                           = modws2_32.NewProc("shutdown")
+	procclosesocket                        = modws2_32.NewProc("closesocket")
+	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
+	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
+	procWSARecv                            = modws2_32.NewProc("WSARecv")
+	procWSASend                            = modws2_32.NewProc("WSASend")
+	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
+	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
+	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
+	procgetservbyname                      = modws2_32.NewProc("getservbyname")
+	procntohs                              = modws2_32.NewProc("ntohs")
+	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
+	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
+	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
+	procDnsNameCompare_W                   = moddnsapi.NewProc("DnsNameCompare_W")
+	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
+	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
+	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
+	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
+	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
+	procGetAdaptersAddresses               = modiphlpapi.NewProc("GetAdaptersAddresses")
+	procGetACP                             = modkernel32.NewProc("GetACP")
+	procMultiByteToWideChar                = modkernel32.NewProc("MultiByteToWideChar")
+	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
+	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
+	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
+	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
+	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
+	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
+	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
+	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
+	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
+	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
+	procCopySid                            = modadvapi32.NewProc("CopySid")
+	procAllocateAndInitializeSid           = modadvapi32.NewProc("AllocateAndInitializeSid")
+	procFreeSid                            = modadvapi32.NewProc("FreeSid")
+	procEqualSid                           = modadvapi32.NewProc("EqualSid")
+	procCheckTokenMembership               = modadvapi32.NewProc("CheckTokenMembership")
+	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
+	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
+	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
+)
+
+func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeregisterEventSource(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CloseServiceHandle(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeleteService(service Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) {
+	r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLastError() (lasterr error) {
+	r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
+	if r0 != 0 {
+		lasterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func LoadLibrary(libname string) (handle Handle, err error) {
+	var _p0 *uint16
+	_p0, err = syscall.UTF16PtrFromString(libname)
+	if err != nil {
+		return
+	}
+	return _LoadLibrary(_p0)
+}
+
+func _LoadLibrary(libname *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) {
+	var _p0 *uint16
+	_p0, err = syscall.UTF16PtrFromString(libname)
+	if err != nil {
+		return
+	}
+	return _LoadLibraryEx(_p0, zero, flags)
+}
+
+func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeLibrary(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(procname)
+	if err != nil {
+		return
+	}
+	return _GetProcAddress(module, _p0)
+}
+
+func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
+	r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
+	proc = uintptr(r0)
+	if proc == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVersion() (ver uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
+	ver = uint32(r0)
+	if ver == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
+	var _p0 *uint16
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ExitProcess(exitcode uint32) {
+	syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
+	return
+}
+
+func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
+	r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
+	newlowoffset = uint32(r0)
+	if newlowoffset == 0xffffffff {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CloseHandle(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetStdHandle(stdhandle uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetStdHandle(stdhandle uint32, handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func findNextFile1(handle Handle, data *win32finddata1) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindClose(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetCurrentDirectory(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func RemoveDirectory(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeleteFile(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MoveFile(from *uint16, to *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetComputerName(buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEndOfFile(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetSystemTimeAsFileTime(time *Filetime) {
+	syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
+	return
+}
+
+func GetSystemTimePreciseAsFileTime(time *Filetime) {
+	syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
+	return
+}
+
+func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
+	rc = uint32(r0)
+	if rc == 0xffffffff {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CancelIo(s Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CancelIoEx(s Handle, o *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+	var _p0 uint32
+	if inheritHandles {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
+	var _p0 uint32
+	if inheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TerminateProcess(handle Handle, exitcode uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetStartupInfo(startupInfo *StartupInfo) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentProcess() (pseudoHandle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
+	pseudoHandle = Handle(r0)
+	if pseudoHandle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
+	var _p0 uint32
+	if bInheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
+	event = uint32(r0)
+	if event == 0xffffffff {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileType(filehandle Handle) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentStrings() (envs *uint16, err error) {
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
+	envs = (*uint16)(unsafe.Pointer(r0))
+	if envs == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeEnvironmentStrings(envs *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
+	r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributes(name *uint16) (attrs uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	attrs = uint32(r0)
+	if attrs == INVALID_FILE_ATTRIBUTES {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFileAttributes(name *uint16, attrs uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCommandLine() (cmd *uint16) {
+	r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
+	cmd = (*uint16)(unsafe.Pointer(r0))
+	return
+}
+
+func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
+	r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
+	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
+	if argv == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func LocalFree(hmem Handle) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
+	handle = Handle(r0)
+	if handle != 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FlushFileBuffers(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
+	r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
+	addr = uintptr(r0)
+	if addr == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func UnmapViewOfFile(addr uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualLock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualUnlock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) {
+	r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0)
+	value = uintptr(r0)
+	if value == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	var _p0 uint32
+	if watchSubTree {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
+	store = Handle(r0)
+	if store == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
+	r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertCloseStore(store Handle, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateChain(ctx *CertChainContext) {
+	syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	return
+}
+
+func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
+	r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateContext(ctx *CertContext) (err error) {
+	r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegCloseKey(key Handle) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func getCurrentProcessId() (pid uint32) {
+	r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
+	pid = uint32(r0)
+	return
+}
+
+func GetConsoleMode(console Handle, mode *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetConsoleMode(console Handle, mode uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
+	r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
+	r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentThreadId() (id uint32) {
+	r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0)
+	id = uint32(r0)
+	return
+}
+
+func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) {
+	var _p0 uint32
+	if inheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name)))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ResetEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func PulseEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindVolumeClose(findVolume Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetDriveType(rootPathName *uint16) (driveType uint32) {
+	r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0)
+	driveType = uint32(r0)
+	return
+}
+
+func GetLogicalDrives() (drivesBitMask uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0)
+	drivesBitMask = uint32(r0)
+	if drivesBitMask == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
+	r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
+	if r0 != 0 {
+		sockerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func WSACleanup() (err error) {
+	r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func listen(s Handle, backlog int32) (err error) {
+	r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func shutdown(s Handle, how int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Closesocket(s Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
+	syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
+	return
+}
+
+func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetHostByName(name string) (h *Hostent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetHostByName(_p0)
+}
+
+func _GetHostByName(name *byte) (h *Hostent, err error) {
+	r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	h = (*Hostent)(unsafe.Pointer(r0))
+	if h == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetServByName(name string, proto string) (s *Servent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = syscall.BytePtrFromString(proto)
+	if err != nil {
+		return
+	}
+	return _GetServByName(_p0, _p1)
+}
+
+func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
+	r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
+	s = (*Servent)(unsafe.Pointer(r0))
+	if s == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Ntohs(netshort uint16) (u uint16) {
+	r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
+	u = uint16(r0)
+	return
+}
+
+func GetProtoByName(name string) (p *Protoent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetProtoByName(_p0)
+}
+
+func _GetProtoByName(name *byte) (p *Protoent, err error) {
+	r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	p = (*Protoent)(unsafe.Pointer(r0))
+	if p == nil {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	var _p0 *uint16
+	_p0, status = syscall.UTF16PtrFromString(name)
+	if status != nil {
+		return
+	}
+	return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
+}
+
+func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
+	if r0 != 0 {
+		status = syscall.Errno(r0)
+	}
+	return
+}
+
+func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
+	syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
+	return
+}
+
+func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
+	r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
+	same = r0 != 0
+	return
+}
+
+func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
+	r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if r0 != 0 {
+		sockerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func FreeAddrInfoW(addrinfo *AddrinfoW) {
+	syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
+	return
+}
+
+func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
+	r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
+	r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
+	n = int32(r0)
+	if n == -1 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func GetACP() (acp uint32) {
+	r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
+	acp = uint32(r0)
+	return
+}
+
+func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
+	r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
+	nwrite = int32(r0)
+	if nwrite == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
+	r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
+	r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func NetApiBufferFree(buf *byte) (neterr error) {
+	r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLengthSid(sid *SID) (len uint32) {
+	r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+	len = uint32(r0)
+	return
+}
+
+func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) {
+	r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeSid(sid *SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+	if r1 != 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) {
+	r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0)
+	isEqual = r0 != 0
+	return
+}
+
+func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
+	r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}