diff --git a/README.md b/README.md
index 4830d9303248a1c953833ea4a2808aeacaafe434..a824e90017525e0c65c42c99522337b25d415774 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ Go Ethereum comes with several binaries found in
 * `mist` Official Ethereum Browser
 * `ethereum` Ethereum CLI
 * `ethtest` test tool which runs with the [tests](https://github.com/ethereum/testes) suit: 
-  `ethtest "`cat myfile.json`"`.
+  `cat file | ethtest`.
 * `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
   10000 -price 0 -dump`. See `-h` for a detailed description.
 
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 93453b91cf85218b343c8cca34dc516160ba052d..4b2cc7bb4a693a9be763f475130d173e6a1c3511 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -1,12 +1,20 @@
 package crypto
 
 import (
+	"crypto/aes"
+	"crypto/cipher"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
 	"crypto/sha256"
 	"fmt"
 
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+
+	"code.google.com/p/go-uuid/uuid"
+	"code.google.com/p/go.crypto/pbkdf2"
 	"code.google.com/p/go.crypto/ripemd160"
 	"github.com/ethereum/go-ethereum/crypto/secp256k1"
 	"github.com/ethereum/go-ethereum/crypto/sha3"
@@ -118,3 +126,100 @@ func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
 	key := ecies.ImportECDSA(prv)
 	return key.Decrypt(rand.Reader, ct, nil, nil)
 }
+
+// creates a Key and stores that in the given KeyStore by decrypting a presale key JSON
+func ImportPreSaleKey(keyStore KeyStore2, keyJSON []byte, password string) (*Key, error) {
+	key, err := decryptPreSaleKey(keyJSON, password)
+	if err != nil {
+		return nil, err
+	}
+	id := uuid.NewRandom()
+	key.Id = &id
+	err = keyStore.StoreKey(key, password)
+	return key, err
+}
+
+func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error) {
+	preSaleKeyStruct := struct {
+		EncSeed string
+		EthAddr string
+		Email   string
+		BtcAddr string
+	}{}
+	err = json.Unmarshal(fileContent, &preSaleKeyStruct)
+	if err != nil {
+		return nil, err
+	}
+	encSeedBytes, err := hex.DecodeString(preSaleKeyStruct.EncSeed)
+	iv := encSeedBytes[:16]
+	cipherText := encSeedBytes[16:]
+	/*
+		See https://github.com/ethereum/pyethsaletool
+
+		pyethsaletool generates the encryption key from password by
+		2000 rounds of PBKDF2 with HMAC-SHA-256 using password as salt (:().
+		16 byte key length within PBKDF2 and resulting key is used as AES key
+	*/
+	passBytes := []byte(password)
+	derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New)
+	plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv)
+	ethPriv := Sha3(plainText)
+	ecKey := ToECDSA(ethPriv)
+	key = &Key{
+		Id:         nil,
+		PrivateKey: ecKey,
+	}
+	derivedAddr := ethutil.Bytes2Hex(key.Address())
+	expectedAddr := preSaleKeyStruct.EthAddr
+	if derivedAddr != expectedAddr {
+		err = errors.New("decrypted addr not equal to expected addr")
+	}
+	return key, err
+}
+
+func aesCBCDecrypt(key []byte, cipherText []byte, iv []byte) (plainText []byte, err error) {
+	aesBlock, err := aes.NewCipher(key)
+	if err != nil {
+		return plainText, err
+	}
+	decrypter := cipher.NewCBCDecrypter(aesBlock, iv)
+	paddedPlainText := make([]byte, len(cipherText))
+	decrypter.CryptBlocks(paddedPlainText, cipherText)
+	plainText = PKCS7Unpad(paddedPlainText)
+	if plainText == nil {
+		err = errors.New("Decryption failed: PKCS7Unpad failed after decryption")
+	}
+	return plainText, err
+}
+
+// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
+func PKCS7Pad(in []byte) []byte {
+	padding := 16 - (len(in) % 16)
+	if padding == 0 {
+		padding = 16
+	}
+	for i := 0; i < padding; i++ {
+		in = append(in, byte(padding))
+	}
+	return in
+}
+
+func PKCS7Unpad(in []byte) []byte {
+	if len(in) == 0 {
+		return nil
+	}
+
+	padding := in[len(in)-1]
+	if int(padding) > len(in) || padding > aes.BlockSize {
+		return nil
+	} else if padding == 0 {
+		return nil
+	}
+
+	for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
+		if in[i] != padding {
+			return nil
+		}
+	}
+	return in[:len(in)-int(padding)]
+}
diff --git a/crypto/key.go b/crypto/key.go
index d371ad4dc9ae24580071a0ebfb026c601c312ab5..ca29b691ff0fc5b234bc0dfe9c78f542a1c8af53 100644
--- a/crypto/key.go
+++ b/crypto/key.go
@@ -57,7 +57,7 @@ type encryptedKeyJSON struct {
 
 func (k *Key) Address() []byte {
 	pubBytes := FromECDSAPub(&k.PrivateKey.PublicKey)
-	return Sha3(pubBytes)[12:]
+	return Sha3(pubBytes[1:])[12:]
 }
 
 func (k *Key) MarshalJSON() (j []byte, err error) {
@@ -99,9 +99,10 @@ func NewKey(rand io.Reader) *Key {
 	privateKeyMarshalled := elliptic.Marshal(S256(), x, y)
 	privateKeyECDSA := ToECDSA(privateKeyMarshalled)
 
-	key := new(Key)
 	id := uuid.NewRandom()
-	key.Id = &id
-	key.PrivateKey = privateKeyECDSA
+	key := &Key{
+		Id:         &id,
+		PrivateKey: privateKeyECDSA,
+	}
 	return key
 }
diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go
index e30a0a785f4685cafcfd69b26c8396fadd283025..80bf49d68a4846a997a5497846dfa8b2af37d2cf 100644
--- a/crypto/key_store_passphrase.go
+++ b/crypto/key_store_passphrase.go
@@ -178,22 +178,10 @@ func DecryptKey(ks keyStorePassphrase, keyId *uuid.UUID, auth string) (keyBytes
 	if err != nil {
 		return nil, err
 	}
-
-	AES256Block, err := aes.NewCipher(derivedKey)
+	plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv)
 	if err != nil {
 		return nil, err
 	}
-
-	AES256CBCDecrypter := cipher.NewCBCDecrypter(AES256Block, iv)
-	paddedPlainText := make([]byte, len(cipherText))
-	AES256CBCDecrypter.CryptBlocks(paddedPlainText, cipherText)
-
-	plainText := PKCS7Unpad(paddedPlainText)
-	if plainText == nil {
-		err = errors.New("Decryption failed: PKCS7Unpad failed after decryption")
-		return nil, err
-	}
-
 	keyBytes = plainText[:len(plainText)-32]
 	keyBytesHash := plainText[len(plainText)-32:]
 	if !bytes.Equal(Sha3(keyBytes), keyBytesHash) {
@@ -211,35 +199,3 @@ func getEntropyCSPRNG(n int) []byte {
 	}
 	return mainBuff
 }
-
-// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
-func PKCS7Pad(in []byte) []byte {
-	padding := 16 - (len(in) % 16)
-	if padding == 0 {
-		padding = 16
-	}
-	for i := 0; i < padding; i++ {
-		in = append(in, byte(padding))
-	}
-	return in
-}
-
-func PKCS7Unpad(in []byte) []byte {
-	if len(in) == 0 {
-		return nil
-	}
-
-	padding := in[len(in)-1]
-	if int(padding) > len(in) || padding > aes.BlockSize {
-		return nil
-	} else if padding == 0 {
-		return nil
-	}
-
-	for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
-		if in[i] != padding {
-			return nil
-		}
-	}
-	return in[:len(in)-int(padding)]
-}
diff --git a/crypto/key_store_test.go b/crypto/key_store_test.go
index 16c0e476d47496f381d621ea7f8e6cfd2895737e..54efc739a2e036407ac6fcee0623c6da9d6bb016 100644
--- a/crypto/key_store_test.go
+++ b/crypto/key_store_test.go
@@ -83,3 +83,16 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
 		t.Fatal(err)
 	}
 }
+
+func TestImportPreSaleKey(t *testing.T) {
+	// file content of a presale key file generated with:
+	// python pyethsaletool.py genwallet
+	// with password "foo"
+	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}"
+	ks := NewKeyStorePassphrase(DefaultDataDir())
+	pass := "foo"
+	_, err := ImportPreSaleKey(ks, []byte(fileContent), pass)
+	if err != nil {
+		t.Fatal(err)
+	}
+}