diff --git a/account/account.go b/account/account.go
index 54f862feaa6ac6501edc3f07c3c3401e96560c5c..d502bd4c7fec4b56a41f061506f9fe24a51ba713 100644
--- a/account/account.go
+++ b/account/account.go
@@ -118,7 +118,7 @@ func NewConcreteAccount(pubKey PublicKey) ConcreteAccount {
 }
 
 func NewConcreteAccountFromSecret(secret string) ConcreteAccount {
-	return NewConcreteAccount(PublicKeyFromPubKey(PrivateKeyFromSecret(secret).PubKey()))
+	return NewConcreteAccount(PublicKeyFromGoCryptoPubKey(PrivateKeyFromSecret(secret).PubKey()))
 }
 
 // Return as immutable Account
diff --git a/account/account_test.go b/account/account_test.go
index 07c30618ee9a195a012913e486e606eefa2db82c..716834e6bbad54189b578f46a565fc4b88500e4e 100644
--- a/account/account_test.go
+++ b/account/account_test.go
@@ -19,8 +19,11 @@ import (
 
 	"encoding/json"
 
+	"fmt"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 )
 
@@ -99,7 +102,11 @@ func TestMarshalJSON(t *testing.T) {
 	concreteAcc.Code = []byte{60, 23, 45}
 	acc := concreteAcc.Account()
 	bs, err := json.Marshal(acc)
-	assert.Equal(t, `{"Address":"745BD6BE33020146E04FA0F293A41E389887DE86","PublicKey":{"type":"ed25519","data":"8CEBC16C166A0614AD7C8E330318E774E1A039321F17274DF12ABA3B1BFC773C"},"Balance":0,"Code":"3C172D","Sequence":0,"StorageRoot":"","Permissions":{"Base":{"Perms":0,"SetBit":0},"Roles":[]}}`,
-		string(bs))
+
+	pubKeyEd25519 := concreteAcc.PublicKey.PubKey.Unwrap().(crypto.PubKeyEd25519)
+	expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"type":"ed25519","data":"%X"},`+
+		`"Balance":0,"Code":"3C172D","Sequence":0,"StorageRoot":"","Permissions":{"Base":{"Perms":0,"SetBit":0},"Roles":[]}}`,
+		concreteAcc.Address, pubKeyEd25519[:])
+	assert.Equal(t, expected, string(bs))
 	assert.NoError(t, err)
 }
diff --git a/account/crypto.go b/account/crypto.go
new file mode 100644
index 0000000000000000000000000000000000000000..e04f257fc362b3940feed9ad06cbb32f326c2001
--- /dev/null
+++ b/account/crypto.go
@@ -0,0 +1,235 @@
+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 {
+	return PublicKey{PubKey: pubKey}
+}
+
+// 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 PublicKey{
+		PubKey: pubKeyEd25519.Wrap(),
+	}, nil
+}
+
+// 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 {
+	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 {
+	return PrivateKey{PrivKey: privKey}
+}
+
+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 PrivateKey{
+		PrivKey: privKeyEd25519.Wrap(),
+	}, nil
+}
+
+// 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
+}
+
+// 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) PublicKey() PublicKey {
+	return PublicKeyFromGoCryptoPubKey(pk.PubKey())
+}
+
+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/crypto_test.go b/account/crypto_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d412e0fc4c83a2ffc4a08088f3ae8182ce90caf5
--- /dev/null
+++ b/account/crypto_test.go
@@ -0,0 +1,28 @@
+package account
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestGeneratePrivateKey(t *testing.T) {
+	privateKey, err := GeneratePrivateKey(bytes.NewBuffer([]byte{
+		1, 2, 3, 4, 5, 6, 7, 8,
+		1, 2, 3, 4, 5, 6, 7, 8,
+		1, 2, 3, 4, 5, 6, 7, 8,
+		1, 2, 3, 4, 5, 6, 7, 8,
+	}))
+	require.NoError(t, err)
+	assert.NoError(t, EnsureEd25519PrivateKeyCorrect(privateKey.RawBytes()))
+	badKey := privateKey.RawBytes()
+	// Change part of the public part to not match private part
+	badKey[35] = 2
+	assert.Error(t, EnsureEd25519PrivateKeyCorrect(badKey))
+	goodKey := privateKey.RawBytes()
+	// Change part of the private part invalidating public part
+	goodKey[31] = 2
+	assert.Error(t, EnsureEd25519PrivateKeyCorrect(badKey))
+}
diff --git a/account/keys.go b/account/keys.go
deleted file mode 100644
index 189a9b318e3882b6209a4beefc83d2d2501d57b2..0000000000000000000000000000000000000000
--- a/account/keys.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package account
-
-import "github.com/tendermint/go-crypto"
-
-// This allows us to control serialisation
-
-type PublicKey struct {
-	crypto.PubKey `json:"unwrap"`
-}
-
-func PublicKeyFromPubKey(pubKey crypto.PubKey) PublicKey {
-	return PublicKey{PubKey: pubKey}
-}
-
-func PrivateKeyFromPrivKey(privKey crypto.PrivKey) PrivateKey {
-	return PrivateKey{PrivKey: privKey}
-}
-
-func (pk PublicKey) Address() Address {
-	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)
-}
-
-type PrivateKey struct {
-	crypto.PrivKey
-}
-
-func (pk PrivateKey) PublicKey() PublicKey {
-	return PublicKeyFromPubKey(pk.PubKey())
-}
-
-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)
-}
diff --git a/account/private_account.go b/account/private_account.go
index 9dc73dbb30e7ec47a3f48ef320b4f30ea460c62f..e1fa11d9b0a57ee78574a62091669d944e5beab7 100644
--- a/account/private_account.go
+++ b/account/private_account.go
@@ -17,15 +17,9 @@ package account
 import (
 	"fmt"
 
-	"github.com/tendermint/ed25519"
-	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 )
 
-type Signer interface {
-	Sign(msg []byte) (crypto.Signature, error)
-}
-
 type PrivateAccount interface {
 	Addressable
 	PrivateKey() PrivateKey
@@ -46,6 +40,20 @@ var _ PrivateAccount = concretePrivateAccountWrapper{}
 
 var _ = wire.RegisterInterface(struct{ PrivateAccount }{}, wire.ConcreteType{concretePrivateAccountWrapper{}, 0x01})
 
+func AsConcretePrivateAccount(privateAccount PrivateAccount) *ConcretePrivateAccount {
+	if privateAccount == nil {
+		return nil
+	}
+	// Avoid a copy
+	if ca, ok := privateAccount.(concretePrivateAccountWrapper); ok {
+		return ca.ConcretePrivateAccount
+	}
+	return &ConcretePrivateAccount{
+		Address:    privateAccount.Address(),
+		PublicKey:  privateAccount.PublicKey(),
+		PrivateKey: privateAccount.PrivateKey(),
+	}
+}
 func (cpaw concretePrivateAccountWrapper) Address() Address {
 	return cpaw.ConcretePrivateAccount.Address
 }
@@ -58,30 +66,22 @@ func (cpaw concretePrivateAccountWrapper) PrivateKey() PrivateKey {
 	return cpaw.ConcretePrivateAccount.PrivateKey
 }
 
-func (pa ConcretePrivateAccount) PrivateAccount() concretePrivateAccountWrapper {
-	return concretePrivateAccountWrapper{&pa}
+func (pa ConcretePrivateAccount) PrivateAccount() PrivateAccount {
+	return concretePrivateAccountWrapper{ConcretePrivateAccount: &pa}
 }
 
-func (pa ConcretePrivateAccount) Sign(msg []byte) (crypto.Signature, error) {
-	return pa.PrivateKey.Sign(msg), nil
+func (pa ConcretePrivateAccount) Sign(msg []byte) (Signature, error) {
+	return pa.PrivateKey.Sign(msg)
 }
 
-func ChainSign(pa PrivateAccount, chainID string, o Signable) crypto.Signature {
-	sig, _ := pa.Sign(SignBytes(chainID, o))
+func ChainSign(pa PrivateAccount, chainID string, o Signable) Signature {
+	sig, err := pa.Sign(SignBytes(chainID, o))
+	if err != nil {
+		panic(err)
+	}
 	return sig
 }
 
-func (pa *ConcretePrivateAccount) Generate(index int) concretePrivateAccountWrapper {
-	newPrivKey := PrivateKeyFromPrivKey(pa.PrivateKey.Unwrap().(crypto.PrivKeyEd25519).Generate(index).Wrap())
-	newPubKey := PublicKeyFromPubKey(newPrivKey.PubKey())
-	newAddress := newPubKey.Address()
-	return ConcretePrivateAccount{
-		Address:    newAddress,
-		PublicKey:  newPubKey,
-		PrivateKey: newPrivKey,
-	}.PrivateAccount()
-}
-
 func (pa *ConcretePrivateAccount) String() string {
 	return fmt.Sprintf("ConcretePrivateAccount{%s}", pa.Address)
 }
@@ -89,48 +89,39 @@ func (pa *ConcretePrivateAccount) String() string {
 //----------------------------------------
 
 // Generates a new account with private key.
-func GeneratePrivateAccount() concretePrivateAccountWrapper {
-	privKeyBytes := new([64]byte)
-	copy(privKeyBytes[:32], crypto.CRandBytes(32))
-	pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
-	publicKey := PublicKeyFromPubKey(crypto.PubKeyEd25519(*pubKeyBytes).Wrap())
-	address := publicKey.Address()
-	privateKey := PrivateKeyFromPrivKey(crypto.PrivKeyEd25519(*privKeyBytes).Wrap())
+func GeneratePrivateAccount() (PrivateAccount, error) {
+	privateKey, err := GeneratePrivateKey(nil)
+	if err != nil {
+		return nil, err
+	}
+	publicKey := privateKey.PublicKey()
 	return ConcretePrivateAccount{
-		Address:    address,
+		Address:    publicKey.Address(),
 		PublicKey:  publicKey,
 		PrivateKey: privateKey,
-	}.PrivateAccount()
-}
-
-func PrivateKeyFromSecret(secret string) PrivateKey {
-	return PrivateKeyFromPrivKey(crypto.GenPrivKeyEd25519FromSecret(wire.BinarySha256(secret)).Wrap())
+	}.PrivateAccount(), nil
 }
 
 // Generates a new account with private key from SHA256 hash of a secret
-func GeneratePrivateAccountFromSecret(secret string) concretePrivateAccountWrapper {
-	privKey := PrivateKeyFromSecret(secret)
-	pubKey := PublicKeyFromPubKey(privKey.PubKey())
+func GeneratePrivateAccountFromSecret(secret string) PrivateAccount {
+	privateKey := PrivateKeyFromSecret(secret)
+	publicKey := privateKey.PublicKey()
 	return ConcretePrivateAccount{
-		Address:    pubKey.Address(),
-		PublicKey:  pubKey,
-		PrivateKey: privKey,
+		Address:    publicKey.Address(),
+		PublicKey:  publicKey,
+		PrivateKey: privateKey,
 	}.PrivateAccount()
 }
 
-func GeneratePrivateAccountFromPrivateKeyBytes(privKeyBytes []byte) concretePrivateAccountWrapper {
-	if len(privKeyBytes) != 64 {
-		panic(fmt.Sprintf("Expected 64 bytes but got %v", len(privKeyBytes)))
+func GeneratePrivateAccountFromPrivateKeyBytes(privKeyBytes []byte) (PrivateAccount, error) {
+	privateKey, err := Ed25519PrivateKeyFromRawBytes(privKeyBytes)
+	if err != nil {
+		return nil, err
 	}
-	var privKeyArray [64]byte
-	copy(privKeyArray[:], privKeyBytes)
-	pubKeyBytes := ed25519.MakePublicKey(&privKeyArray)
-	publicKey := PublicKeyFromPubKey(crypto.PubKeyEd25519(*pubKeyBytes).Wrap())
-	address := publicKey.Address()
-	privateKey := PrivateKeyFromPrivKey(crypto.PrivKeyEd25519(privKeyArray).Wrap())
+	publicKey := privateKey.PublicKey()
 	return ConcretePrivateAccount{
-		Address:    address,
+		Address:    publicKey.Address(),
 		PublicKey:  publicKey,
 		PrivateKey: privateKey,
-	}.PrivateAccount()
+	}.PrivateAccount(), nil
 }
diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go
index 1289774c9aa2bafc5191d09e467ae800ffb1e28c..9ae5f1923c53bc7f17aca2fbd307ddbd52e05a42 100644
--- a/client/mock/client_mock.go
+++ b/client/mock/client_mock.go
@@ -53,7 +53,7 @@ func (mock *MockNodeClient) GetAccount(address acm.Address) (acm.Account, error)
 	// make zero account
 	return acm.ConcreteAccount{
 		Address:     address,
-		PublicKey:   acm.PublicKeyFromPubKey(crypto.PubKeyEd25519{}.Wrap()),
+		PublicKey:   acm.PublicKeyFromGoCryptoPubKey(crypto.PubKeyEd25519{}.Wrap()),
 		Code:        make([]byte, 0),
 		StorageRoot: make([]byte, 0),
 	}.Account(), nil
diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go
index 8ad34c261e2787ea75e14cf73b9cf860f2548ee8..1afb93c98bbff50fbd809c0195a0985a13bd8e9d 100644
--- a/client/rpc/client_util.go
+++ b/client/rpc/client_util.go
@@ -26,7 +26,6 @@ import (
 	"github.com/hyperledger/burrow/permission"
 	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/hyperledger/burrow/txs"
-	"github.com/tendermint/go-crypto"
 )
 
 //------------------------------------------------------------------------------------
@@ -115,10 +114,10 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			err = fmt.Errorf("pubkey is bad hex: %v", err)
 			return
 		}
-
-		pubKeyEd25519 := crypto.PubKeyEd25519{}
-		copy(pubKeyEd25519[:], pubKeyBytes)
-		pub = acm.PublicKeyFromPubKey(pubKeyEd25519.Wrap())
+		pub, err = acm.PublicKeyFromBytes(pubKeyBytes)
+		if err != nil {
+			return
+		}
 	} else {
 		// grab the pubkey from monax-keys
 		addressBytes, err2 := hex.DecodeString(addr)
diff --git a/consensus/tendermint/query/node_view.go b/consensus/tendermint/query/node_view.go
index 69949436a27d1966971869927d326d28da5eb33b..7aa451766e419053cfecfe9b31071b0286e27497 100644
--- a/consensus/tendermint/query/node_view.go
+++ b/consensus/tendermint/query/node_view.go
@@ -47,7 +47,7 @@ func NewNodeView(tmNode *node.Node, txDecoder txs.Decoder) NodeView {
 }
 
 func (nv *nodeView) PrivValidatorPublicKey() acm.PublicKey {
-	return acm.PublicKeyFromPubKey(nv.tmNode.PrivValidator().GetPubKey())
+	return acm.PublicKeyFromGoCryptoPubKey(nv.tmNode.PrivValidator().GetPubKey())
 }
 
 func (nv *nodeView) NodeInfo() *p2p.NodeInfo {
diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go
index f8581144758dcdd0f519f26c4d777d8cc471c0df..90a51fa9f095bf4b4ae202bb7077e1fc80c4e03d 100644
--- a/consensus/tendermint/validator/priv_validator_memory.go
+++ b/consensus/tendermint/validator/priv_validator_memory.go
@@ -34,13 +34,29 @@ func (pvm *privValidatorMemory) GetPubKey() crypto.PubKey {
 }
 
 func (pvm *privValidatorMemory) SignVote(chainID string, vote *tm_types.Vote) error {
-	return pvm.lastSignedInfo.SignVote(pvm, chainID, vote)
+	return pvm.lastSignedInfo.SignVote(asTendermintSigner(pvm.Signer), chainID, vote)
 }
 
 func (pvm *privValidatorMemory) SignProposal(chainID string, proposal *tm_types.Proposal) error {
-	return pvm.lastSignedInfo.SignProposal(pvm, chainID, proposal)
+	return pvm.lastSignedInfo.SignProposal(asTendermintSigner(pvm.Signer), chainID, proposal)
 }
 
 func (pvm *privValidatorMemory) SignHeartbeat(chainID string, heartbeat *tm_types.Heartbeat) error {
-	return pvm.lastSignedInfo.SignHeartbeat(pvm, chainID, heartbeat)
+	return pvm.lastSignedInfo.SignHeartbeat(asTendermintSigner(pvm.Signer), chainID, heartbeat)
+}
+
+func asTendermintSigner(signer acm.Signer) tm_types.Signer {
+	return tendermintSigner{Signer: signer}
+}
+
+type tendermintSigner struct {
+	acm.Signer
+}
+
+func (tms tendermintSigner) Sign(msg []byte) (crypto.Signature, error) {
+	sig, err := tms.Signer.Sign(msg)
+	if err != nil {
+		return crypto.Signature{}, err
+	}
+	return sig.GoCryptoSignature(), nil
 }
diff --git a/execution/accounts.go b/execution/accounts.go
index 0e9d1bd138e15b360e1d91c53f970664576da7be..8a54e2f5a368542211afd38d5f4eeede165b8c59 100644
--- a/execution/accounts.go
+++ b/execution/accounts.go
@@ -77,8 +77,11 @@ func newAccounts(state acm.StateIterable) *accounts {
 
 // Generate a new Private Key Account.
 func (accs *accounts) GenPrivAccount() (*acm.ConcretePrivateAccount, error) {
-	pa := acm.GeneratePrivateAccount().ConcretePrivateAccount
-	return pa, nil
+	pa, err := acm.GeneratePrivateAccount()
+	if err != nil {
+		return nil, err
+	}
+	return acm.AsConcretePrivateAccount(pa), nil
 }
 
 // Generate a new Private Key Account.
@@ -88,8 +91,11 @@ func (accs *accounts) GenPrivAccountFromKey(privKey []byte) (
 		return nil, fmt.Errorf("Private key is not 64 bytes long.")
 	}
 	fmt.Printf("PK BYTES FROM ACCOUNTS: %x\n", privKey)
-	pa := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey).ConcretePrivateAccount
-	return pa, nil
+	pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	if err != nil {
+		return nil, err
+	}
+	return acm.AsConcretePrivateAccount(pa), nil
 }
 
 // Get all accounts.
diff --git a/execution/transactor.go b/execution/transactor.go
index fc917c07b065cc2c1b1c92230b55043d3da21e83..90df6728900fd3cbfb963916ad4b072eda3a7376 100644
--- a/execution/transactor.go
+++ b/execution/transactor.go
@@ -175,7 +175,10 @@ func (trans *transactor) Transact(privKey []byte, address acm.Address, data []by
 	}
 	trans.txMtx.Lock()
 	defer trans.txMtx.Unlock()
-	pa := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	if err != nil {
+		return nil, err
+	}
 	// [Silas] This is puzzling, if the account doesn't exist the CallTx will fail, so what's the point in this?
 	acc, err := trans.state.GetAccount(pa.Address())
 	if err != nil {
@@ -289,7 +292,10 @@ func (trans *transactor) Send(privKey []byte, toAddress acm.Address, amount uint
 	copy(pk[:], privKey)
 	trans.txMtx.Lock()
 	defer trans.txMtx.Unlock()
-	pa := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	if err != nil {
+		return nil, err
+	}
 	cache := trans.state
 	acc, err := cache.GetAccount(pa.Address())
 	if err != nil {
@@ -359,7 +365,10 @@ func (trans *transactor) SendAndHold(privKey []byte, toAddress acm.Address, amou
 
 	var rErr error
 
-	pa := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	if tErr != nil {
+		return nil, err
+	}
 
 	select {
 	case <-toChan:
@@ -381,7 +390,10 @@ func (trans *transactor) TransactNameReg(privKey []byte, name, data string, amou
 	}
 	trans.txMtx.Lock()
 	defer trans.txMtx.Unlock()
-	pa := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKey)
+	if err != nil {
+		return nil, err
+	}
 	cache := trans.state // XXX: DON'T MUTATE THIS CACHE (used internally for CheckTx)
 	acc, err := cache.GetAccount(pa.Address())
 	if err != nil {
diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go
index 7eebd858da93ea33b22e816b6bf2f5ae63337a6c..19d94cbf3cbd1d7c922732fdac67e4b6d5acd0f1 100644
--- a/genesis/deterministic_genesis.go
+++ b/genesis/deterministic_genesis.go
@@ -1,15 +1,12 @@
 package genesis
 
 import (
+	"fmt"
 	"math/rand"
 	"time"
 
-	"fmt"
-
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/permission"
-	"github.com/tendermint/ed25519"
-	"github.com/tendermint/go-crypto"
 )
 
 type deterministicGenesis struct {
@@ -67,8 +64,11 @@ func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, mi
 }
 
 func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (acm.Account, acm.PrivateAccount) {
-	privKey := dg.PrivateKey()
-	pubKey := acm.PublicKeyFromPubKey(privKey.PubKey())
+	privKey, err := acm.GeneratePrivateKey(dg.random)
+	if err != nil {
+		panic(fmt.Errorf("could not generate private key deterministically"))
+	}
+	pubKey := acm.PublicKeyFromGoCryptoPubKey(privKey.PubKey())
 	privAccount := &acm.ConcretePrivateAccount{
 		PublicKey:  pubKey,
 		PrivateKey: privKey,
@@ -87,12 +87,3 @@ func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (ac
 	}
 	return acc.Account(), privAccount.PrivateAccount()
 }
-
-func (dg *deterministicGenesis) PrivateKey() acm.PrivateKey {
-	privKeyBytes := new([64]byte)
-	for i := 0; i < 32; i++ {
-		privKeyBytes[i] = byte(dg.random.Int() % 256)
-	}
-	ed25519.MakePublicKey(privKeyBytes)
-	return acm.PrivateKeyFromPrivKey(crypto.PrivKeyEd25519(*privKeyBytes).Wrap())
-}
diff --git a/keys/key_client.go b/keys/key_client.go
index 5ca92be2498c77a641445497288af0758ebccbab..2afb5ce3132ccdd266dab9795cc35234479d17a2 100644
--- a/keys/key_client.go
+++ b/keys/key_client.go
@@ -15,19 +15,17 @@
 package keys
 
 import (
-	"bytes"
 	"encoding/hex"
 	"fmt"
 
 	acm "github.com/hyperledger/burrow/account"
 	"github.com/hyperledger/burrow/logging"
 	logging_types "github.com/hyperledger/burrow/logging/types"
-	"github.com/tendermint/go-crypto"
 )
 
 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 crypto.Signature, err error)
+	Sign(signAddress acm.Address, message []byte) (signature acm.Signature, err error)
 
 	// PublicKey returns the public key associated with a given address
 	PublicKey(address acm.Address) (publicKey acm.PublicKey, err error)
@@ -35,7 +33,7 @@ type KeyClient interface {
 	// 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)
 
-	// Returns nil if the keys isntance is health, error otherwise
+	// Returns nil if the keys instance is healthy, error otherwise
 	HealthCheck() error
 }
 
@@ -57,16 +55,16 @@ const (
 	KeyTypeDefault                          = KeyTypeEd25519Ripemd160
 )
 
-// NOTE [ben] Compiler check to ensure monaxKeyClient successfully implements
+// NOTE [ben] Compiler check to ensure keyClient successfully implements
 // burrow/keys.KeyClient
-var _ KeyClient = (*monaxKeyClient)(nil)
+var _ KeyClient = (*keyClient)(nil)
 
-type monaxKeyClient struct {
+type keyClient struct {
 	rpcString string
 	logger    logging_types.InfoTraceLogger
 }
 
-type monaxSigner struct {
+type signer struct {
 	keyClient KeyClient
 	address   acm.Address
 }
@@ -74,7 +72,7 @@ type monaxSigner struct {
 // Creates a Signer that assumes the address holds an Ed25519 key
 func Signer(keyClient KeyClient, address acm.Address) acm.Signer {
 	// TODO: we can do better than this and return a typed signature when we reform the keys service
-	return &monaxSigner{
+	return &signer{
 		keyClient: keyClient,
 		address:   address,
 	}
@@ -104,18 +102,18 @@ func Addressable(keyClient KeyClient, address acm.Address) (acm.Addressable, err
 	}, nil
 }
 
-func (ms *monaxSigner) Sign(messsage []byte) (crypto.Signature, error) {
+func (ms *signer) Sign(messsage []byte) (acm.Signature, error) {
 	signature, err := ms.keyClient.Sign(ms.address, messsage)
 	if err != nil {
-		return crypto.Signature{}, err
+		return acm.Signature{}, err
 	}
 	return signature, nil
 }
 
-// monaxKeyClient.New returns a new monax-keys client for provided rpc location
+// keyClient.New returns a new monax-keys client for provided rpc location
 // Monax-keys connects over http request-responses
-func NewBurrowKeyClient(rpcString string, logger logging_types.InfoTraceLogger) *monaxKeyClient {
-	return &monaxKeyClient{
+func NewBurrowKeyClient(rpcString string, logger logging_types.InfoTraceLogger) *keyClient {
+	return &keyClient{
 		rpcString: rpcString,
 		logger:    logging.WithScope(logger, "BurrowKeyClient"),
 	}
@@ -123,25 +121,25 @@ func NewBurrowKeyClient(rpcString string, logger logging_types.InfoTraceLogger)
 
 // 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 (monaxKeys *monaxKeyClient) Sign(signAddress acm.Address, message []byte) (crypto.Signature, error) {
+func (monaxKeys *keyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
 	args := map[string]string{
 		"msg":  hex.EncodeToString(message),
 		"addr": signAddress.String(),
 	}
 	sigS, err := RequestResponse(monaxKeys.rpcString, "sign", args, monaxKeys.logger)
 	if err != nil {
-		return crypto.Signature{}, err
+		return acm.Signature{}, err
 	}
 	sigBytes, err := hex.DecodeString(sigS)
 	if err != nil {
-		return crypto.Signature{}, err
+		return acm.Signature{}, err
 	}
-	return crypto.SignatureEd25519FromBytes(sigBytes), err
+	return acm.SignatureFromBytes(sigBytes)
 }
 
 // Monax-keys client PublicKey requests the public key associated with an address from
 // the monax-keys server.
-func (monaxKeys *monaxKeyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
+func (monaxKeys *keyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
 	args := map[string]string{
 		"addr": address.String(),
 	}
@@ -149,20 +147,22 @@ func (monaxKeys *monaxKeyClient) PublicKey(address acm.Address) (acm.PublicKey,
 	if err != nil {
 		return acm.PublicKey{}, err
 	}
-	pubKey := crypto.PubKeyEd25519{}
 	pubKeyBytes, err := hex.DecodeString(pubS)
 	if err != nil {
 		return acm.PublicKey{}, err
 	}
-	copy(pubKey[:], pubKeyBytes)
-	if !bytes.Equal(address.Bytes(), pubKey.Address()) {
-		return acm.PublicKey{}, fmt.Errorf("public key %s maps to address %X but was returned for address %s",
-			pubKey, pubKey.Address(), address)
+	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 acm.PublicKeyFromPubKey(pubKey.Wrap()), nil
+	return publicKey, nil
 }
 
-func (monaxKeys *monaxKeyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) {
+func (monaxKeys *keyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) {
 	args := map[string]string{
 		//"auth": auth,
 		"name": keyName,
@@ -175,7 +175,7 @@ func (monaxKeys *monaxKeyClient) Generate(keyName string, keyType KeyType) (acm.
 	return acm.AddressFromHexString(addr)
 }
 
-func (monaxKeys *monaxKeyClient) HealthCheck() error {
+func (monaxKeys *keyClient) HealthCheck() error {
 	_, err := RequestResponse(monaxKeys.rpcString, "name/ls", nil, monaxKeys.logger)
 	return err
 }
diff --git a/keys/key_client_test.go b/keys/key_client_test.go
index 4c483c789cafbb6187233595c2ea78686d16d811..127a677e7d4d24c6a365534117864391e717e932 100644
--- a/keys/key_client_test.go
+++ b/keys/key_client_test.go
@@ -28,7 +28,7 @@ func TestMain(m *testing.M) {
 		fatalf("couldn't create temp dir: %v", err)
 	}
 	go keys.StartServer(keysHost, keysPort)
-	m.Run()
+	os.Exit(m.Run())
 }
 
 func TestMonaxKeyClient_Generate(t *testing.T) {
@@ -43,7 +43,7 @@ func TestMonaxKeyClient_PublicKey(t *testing.T) {
 	addr, err := keyClient.Generate("I'm a lovely hat", KeyTypeEd25519Ripemd160)
 	assert.NoError(t, err)
 	pubKey, err := keyClient.PublicKey(addr)
-	assert.Equal(t, addr[:], pubKey.Address())
+	assert.Equal(t, addr, pubKey.Address())
 }
 
 func TestMonaxKeyClient_PublicKey_NonExistent(t *testing.T) {
diff --git a/keys/mock/key_client_mock.go b/keys/mock/key_client_mock.go
index 4a31a0fb2831f5372ef5062f4358eb5ac61eec23..53b311aed212eba77c4c7e42ca8fe36e2946e33c 100644
--- a/keys/mock/key_client_mock.go
+++ b/keys/mock/key_client_mock.go
@@ -21,7 +21,7 @@ import (
 	acm "github.com/hyperledger/burrow/account"
 	. "github.com/hyperledger/burrow/keys"
 	"github.com/tendermint/ed25519"
-	"github.com/tendermint/go-crypto"
+	crypto "github.com/tendermint/go-crypto"
 	"golang.org/x/crypto/ripemd160"
 )
 
@@ -59,11 +59,8 @@ func newMockKey() (*MockKey, error) {
 	return key, nil
 }
 
-func (mockKey *MockKey) Sign(message []byte) (crypto.Signature, error) {
-	sigEd25519 := crypto.SignatureEd25519{}
-	signatureBytes := ed25519.Sign(&mockKey.PrivateKey, message)
-	copy(sigEd25519[:], signatureBytes[:])
-	return sigEd25519.Wrap(), nil
+func (mockKey *MockKey) Sign(message []byte) (acm.Signature, error) {
+	return acm.SignatureFromBytes(ed25519.Sign(&mockKey.PrivateKey, message)[:])
 }
 
 //---------------------------------------------------------------------
@@ -92,10 +89,10 @@ func (mock *MockKeyClient) NewKey() acm.Address {
 	return key.Address
 }
 
-func (mock *MockKeyClient) Sign(signAddress acm.Address, message []byte) (crypto.Signature, error) {
+func (mock *MockKeyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
 	key := mock.knownKeys[signAddress]
 	if key == nil {
-		return crypto.Signature{}, fmt.Errorf("Unknown address (%s)", signAddress)
+		return acm.Signature{}, fmt.Errorf("Unknown address (%s)", signAddress)
 	}
 	return key.Sign(message)
 }
@@ -107,7 +104,7 @@ func (mock *MockKeyClient) PublicKey(address acm.Address) (acm.PublicKey, error)
 	}
 	pubKeyEd25519 := crypto.PubKeyEd25519{}
 	copy(pubKeyEd25519[:], key.PublicKey)
-	return acm.PublicKeyFromPubKey(pubKeyEd25519.Wrap()), nil
+	return acm.PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap()), nil
 }
 
 func (mock *MockKeyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) {
diff --git a/rpc/service.go b/rpc/service.go
index b2fc8454be2d56643475d6cb46803ed6d87e3a98..8dfcbdd5a85b8801fd97849950bd5e8caa353f62 100644
--- a/rpc/service.go
+++ b/rpc/service.go
@@ -395,7 +395,11 @@ func (s *service) SignTx(tx txs.Tx, concretePrivateAccounts []*acm.ConcretePriva
 }
 
 func (s *service) GeneratePrivateAccount() (*ResultGeneratePrivateAccount, error) {
+	privateAccount, err := acm.GeneratePrivateAccount()
+	if err != nil {
+		return nil, err
+	}
 	return &ResultGeneratePrivateAccount{
-		PrivAccount: acm.GeneratePrivateAccount().ConcretePrivateAccount,
+		PrivAccount: acm.AsConcretePrivateAccount(privateAccount),
 	}, nil
 }
diff --git a/txs/tx.go b/txs/tx.go
index 1cb2ea1b40e654562bc09457bfd78ff182edc064..6d061b04522d59d623e6be789da4a8be5dc9ea96 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -22,7 +22,6 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	ptypes "github.com/hyperledger/burrow/permission"
-	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 	"github.com/tendermint/go-wire/data"
 	"golang.org/x/crypto/ripemd160"
@@ -149,11 +148,11 @@ type (
 	}
 
 	TxInput struct {
-		Address   acm.Address      `json:"address"`   // Hash of the PublicKey
-		Amount    uint64           `json:"amount"`    // Must not exceed account balance
-		Sequence  uint64           `json:"sequence"`  // Must be 1 greater than the last committed TxInput
-		Signature crypto.Signature `json:"signature"` // Depends on the PublicKey type and the whole Tx
-		PubKey    acm.PublicKey    `json:"pub_key"`   // Must not be nil, may be nil
+		Address   acm.Address   `json:"address"`   // Hash of the PublicKey
+		Amount    uint64        `json:"amount"`    // Must not exceed account balance
+		Sequence  uint64        `json:"sequence"`  // Must be 1 greater than the last committed TxInput
+		Signature acm.Signature `json:"signature"` // Depends on the PublicKey type and the whole Tx
+		PubKey    acm.PublicKey `json:"pub_key"`   // Must not be nil, may be nil
 	}
 
 	TxOutput struct {
@@ -311,10 +310,10 @@ func (tx *NameTx) String() string {
 //-----------------------------------------------------------------------------
 
 type BondTx struct {
-	PubKey    acm.PublicKey    `json:"pub_key"` // NOTE: these don't have type byte
-	Signature crypto.Signature `json:"signature"`
-	Inputs    []*TxInput       `json:"inputs"`
-	UnbondTo  []*TxOutput      `json:"unbond_to"`
+	PubKey    acm.PublicKey `json:"pub_key"` // NOTE: these don't have type byte
+	Signature acm.Signature `json:"signature"`
+	Inputs    []*TxInput    `json:"inputs"`
+	UnbondTo  []*TxOutput   `json:"unbond_to"`
 }
 
 func (tx *BondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
@@ -345,9 +344,9 @@ func (tx *BondTx) String() string {
 //-----------------------------------------------------------------------------
 
 type UnbondTx struct {
-	Address   acm.Address      `json:"address"`
-	Height    int              `json:"height"`
-	Signature crypto.Signature `json:"signature"`
+	Address   acm.Address   `json:"address"`
+	Height    int           `json:"height"`
+	Signature acm.Signature `json:"signature"`
 }
 
 func (tx *UnbondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
@@ -362,9 +361,9 @@ func (tx *UnbondTx) String() string {
 //-----------------------------------------------------------------------------
 
 type RebondTx struct {
-	Address   acm.Address      `json:"address"`
-	Height    int              `json:"height"`
-	Signature crypto.Signature `json:"signature"`
+	Address   acm.Address   `json:"address"`
+	Height    int           `json:"height"`
+	Signature acm.Signature `json:"signature"`
 }
 
 func (tx *RebondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
@@ -379,7 +378,7 @@ func (tx *RebondTx) String() string {
 //-----------------------------------------------------------------------------
 
 type PermissionsTx struct {
-	Input    *TxInput        `json:"input"`
+	Input    *TxInput         `json:"input"`
 	PermArgs *ptypes.PermArgs `json:"args"`
 }
 
diff --git a/txs/tx_test.go b/txs/tx_test.go
index c8c39a6200c9c5172594ab88fcf900b10bf5cd93..7ec8f44004742ab8bf7c63bd2a278d44877c88f0 100644
--- a/txs/tx_test.go
+++ b/txs/tx_test.go
@@ -111,8 +111,7 @@ func TestNameTxSignable(t *testing.T) {
 }
 
 func TestBondTxSignable(t *testing.T) {
-	privKeyBytes := make([]byte, 64)
-	privAccount := acm.GeneratePrivateAccountFromPrivateKeyBytes(privKeyBytes)
+	privAccount := acm.GeneratePrivateAccountFromSecret("foooobars")
 	bondTx := &BondTx{
 		PubKey: privAccount.PublicKey(),
 		Inputs: []*TxInput{
@@ -138,8 +137,20 @@ 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,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"%s","amount":333},{"address":"%s","amount":444}]}]}`,
-		chainID, bondTx.Inputs[0].Address.String(), bondTx.Inputs[1].Address.String(), bondTx.UnbondTo[0].Address.String(), bondTx.UnbondTo[1].Address.String())
+	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"],`+
+		`"unbond_to":[{"address":"%s",`+
+		`"amount":333},{"address":"%s",`+
+		`"amount":444}]}]}`,
+		chainID,
+		bondTx.Inputs[0].Address.String(),
+		bondTx.Inputs[1].Address.String(),
+		bondTx.PubKey.RawBytes(),
+		bondTx.UnbondTo[0].Address.String(),
+		bondTx.UnbondTo[1].Address.String())
+
 	assert.Equal(t, expected, string(acm.SignBytes(chainID, bondTx)), "Unexpected sign string for BondTx")
 }
 
diff --git a/txs/tx_utils.go b/txs/tx_utils.go
index 1b2d65fe3f3a693c41c7fe29e51022c8e1971d6f..753f3e3229273d7ae6970f3435f3f2cf975d981e 100644
--- a/txs/tx_utils.go
+++ b/txs/tx_utils.go
@@ -19,8 +19,6 @@ import (
 
 	acm "github.com/hyperledger/burrow/account"
 	ptypes "github.com/hyperledger/burrow/permission"
-
-	"github.com/tendermint/go-crypto"
 )
 
 //----------------------------------------------------------------------------
@@ -51,7 +49,6 @@ func (tx *SendTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc
 		Address:   addr,
 		Amount:    amt,
 		Sequence:  sequence,
-		Signature: crypto.SignatureEd25519{}.Wrap(),
 		PubKey:    pubkey,
 	})
 	return nil
@@ -99,7 +96,6 @@ func NewCallTxWithSequence(from acm.PublicKey, to *acm.Address, data []byte,
 		Address:   from.Address(),
 		Amount:    amt,
 		Sequence:  sequence,
-		Signature: crypto.SignatureEd25519{}.Wrap(),
 		PubKey:    from,
 	}
 
@@ -139,7 +135,6 @@ func NewNameTxWithSequence(from acm.PublicKey, name, data string, amt, fee, sequ
 		Address:   from.Address(),
 		Amount:    amt,
 		Sequence:  sequence,
-		Signature: crypto.SignatureEd25519{}.Wrap(),
 		PubKey:    from,
 	}
 
@@ -184,7 +179,6 @@ func (tx *BondTx) AddInputWithSequence(pubkey acm.PublicKey, amt uint64, sequenc
 		Address:   pubkey.Address(),
 		Amount:    amt,
 		Sequence:  sequence,
-		Signature: crypto.SignatureEd25519{}.Wrap(),
 		PubKey:    pubkey,
 	})
 	return nil
@@ -262,7 +256,6 @@ func NewPermissionsTxWithSequence(from acm.PublicKey, args *ptypes.PermArgs, seq
 		Address:   from.Address(),
 		Amount:    1, // NOTE: amounts can't be 0 ...
 		Sequence:  sequence,
-		Signature: crypto.SignatureEd25519{}.Wrap(),
 		PubKey:    from,
 	}