| 
									
										
										
										
											2014-10-31 12:37:43 +01:00
										 |  |  | package crypto | 
					
						
							| 
									
										
										
										
											2014-06-29 15:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	"crypto/aes" | 
					
						
							|  |  |  | 	"crypto/cipher" | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | 	"crypto/ecdsa" | 
					
						
							|  |  |  | 	"crypto/elliptic" | 
					
						
							|  |  |  | 	"crypto/rand" | 
					
						
							| 
									
										
										
										
											2014-10-08 12:00:50 +02:00
										 |  |  | 	"crypto/sha256" | 
					
						
							| 
									
										
										
										
											2015-01-22 18:12:05 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-03-25 14:58:52 +00:00
										 |  |  | 	"io/ioutil" | 
					
						
							| 
									
										
										
										
											2015-06-01 20:27:20 +02:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2014-10-08 12:00:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 22:42:39 +01:00
										 |  |  | 	"encoding/hex" | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2014-10-08 12:00:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	"code.google.com/p/go-uuid/uuid" | 
					
						
							| 
									
										
										
										
											2015-03-16 17:27:24 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-02-14 00:25:47 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto/ecies" | 
					
						
							| 
									
										
										
										
											2015-01-22 00:35:00 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto/secp256k1" | 
					
						
							| 
									
										
										
										
											2015-01-22 00:25:00 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto/sha3" | 
					
						
							| 
									
										
										
										
											2015-03-17 11:19:23 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2015-02-17 13:05:58 +01:00
										 |  |  | 	"golang.org/x/crypto/pbkdf2" | 
					
						
							|  |  |  | 	"golang.org/x/crypto/ripemd160" | 
					
						
							| 
									
										
										
										
											2014-06-29 15:57:12 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-03 14:44:29 +02:00
										 |  |  | var secp256k1n *big.Int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | func init() { | 
					
						
							|  |  |  | 	// specify the params for the s256 curve | 
					
						
							|  |  |  | 	ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256) | 
					
						
							| 
									
										
										
										
											2015-06-03 14:44:29 +02:00
										 |  |  | 	secp256k1n = common.String2Big("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141") | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-27 14:29:33 +01:00
										 |  |  | func Sha3(data ...[]byte) []byte { | 
					
						
							| 
									
										
										
										
											2014-06-29 15:57:12 +01:00
										 |  |  | 	d := sha3.NewKeccak256() | 
					
						
							| 
									
										
										
										
											2015-01-27 14:29:33 +01:00
										 |  |  | 	for _, b := range data { | 
					
						
							|  |  |  | 		d.Write(b) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-29 15:57:12 +01:00
										 |  |  | 	return d.Sum(nil) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-29 16:08:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 17:27:24 +01:00
										 |  |  | func Sha3Hash(data ...[]byte) (h common.Hash) { | 
					
						
							|  |  |  | 	d := sha3.NewKeccak256() | 
					
						
							|  |  |  | 	for _, b := range data { | 
					
						
							|  |  |  | 		d.Write(b) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-17 01:32:35 +01:00
										 |  |  | 	d.Sum(h[:0]) | 
					
						
							| 
									
										
										
										
											2015-03-16 17:27:24 +01:00
										 |  |  | 	return h | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 16:08:33 +01:00
										 |  |  | // Creates an ethereum address given the bytes and the nonce | 
					
						
							| 
									
										
										
										
											2015-03-17 11:19:23 +01:00
										 |  |  | func CreateAddress(b common.Address, nonce uint64) common.Address { | 
					
						
							|  |  |  | 	data, _ := rlp.EncodeToBytes([]interface{}{b, nonce}) | 
					
						
							|  |  |  | 	return common.BytesToAddress(Sha3(data)[12:]) | 
					
						
							|  |  |  | 	//return Sha3(common.NewValue([]interface{}{b, nonce}).Encode())[12:] | 
					
						
							| 
									
										
										
										
											2014-06-29 16:08:33 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-08 12:00:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func Sha256(data []byte) []byte { | 
					
						
							|  |  |  | 	hash := sha256.Sum256(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hash[:] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Ripemd160(data []byte) []byte { | 
					
						
							|  |  |  | 	ripemd := ripemd160.New() | 
					
						
							|  |  |  | 	ripemd.Write(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ripemd.Sum(nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-05 19:31:18 +02:00
										 |  |  | func Ecrecover(hash, sig []byte) ([]byte, error) { | 
					
						
							|  |  |  | 	return secp256k1.RecoverPubkey(hash, sig) | 
					
						
							| 
									
										
										
										
											2014-10-08 12:00:50 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | // New methods using proper ecdsa keys from the stdlib | 
					
						
							|  |  |  | func ToECDSA(prv []byte) *ecdsa.PrivateKey { | 
					
						
							| 
									
										
										
										
											2014-12-12 22:24:04 +01:00
										 |  |  | 	if len(prv) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 	priv := new(ecdsa.PrivateKey) | 
					
						
							|  |  |  | 	priv.PublicKey.Curve = S256() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	priv.D = common.BigD(prv) | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 	priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(prv) | 
					
						
							|  |  |  | 	return priv | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | func FromECDSA(prv *ecdsa.PrivateKey) []byte { | 
					
						
							| 
									
										
										
										
											2014-12-12 22:24:04 +01:00
										 |  |  | 	if prv == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 	return prv.D.Bytes() | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 22:24:04 +01:00
										 |  |  | func ToECDSAPub(pub []byte) *ecdsa.PublicKey { | 
					
						
							|  |  |  | 	if len(pub) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | 	x, y := elliptic.Unmarshal(S256(), pub) | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 	return &ecdsa.PublicKey{S256(), x, y} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 22:24:04 +01:00
										 |  |  | func FromECDSAPub(pub *ecdsa.PublicKey) []byte { | 
					
						
							| 
									
										
										
										
											2015-01-30 13:24:20 +01:00
										 |  |  | 	if pub == nil || pub.X == nil || pub.Y == nil { | 
					
						
							| 
									
										
										
										
											2014-12-12 22:24:04 +01:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return elliptic.Marshal(S256(), pub.X, pub.Y) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | // HexToECDSA parses a secp256k1 private key. | 
					
						
							|  |  |  | func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) { | 
					
						
							|  |  |  | 	b, err := hex.DecodeString(hexkey) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, errors.New("invalid hex string") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if len(b) != 32 { | 
					
						
							|  |  |  | 		return nil, errors.New("invalid length, need 256 bits") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ToECDSA(b), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadECDSA loads a secp256k1 private key from the given file. | 
					
						
							| 
									
										
										
										
											2015-04-19 01:33:00 +02:00
										 |  |  | // The key data is expected to be hex-encoded. | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | func LoadECDSA(file string) (*ecdsa.PrivateKey, error) { | 
					
						
							| 
									
										
										
										
											2015-04-08 23:03:47 +02:00
										 |  |  | 	buf := make([]byte, 64) | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | 	fd, err := os.Open(file) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer fd.Close() | 
					
						
							|  |  |  | 	if _, err := io.ReadFull(fd, buf); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-09 10:59:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	key, err := hex.DecodeString(string(buf)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ToECDSA(key), nil | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-19 01:33:00 +02:00
										 |  |  | // SaveECDSA saves a secp256k1 private key to the given file with | 
					
						
							|  |  |  | // restrictive permissions. The key data is saved hex-encoded. | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | func SaveECDSA(file string, key *ecdsa.PrivateKey) error { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:59:37 +02:00
										 |  |  | 	k := hex.EncodeToString(FromECDSA(key)) | 
					
						
							|  |  |  | 	return ioutil.WriteFile(file, []byte(k), 0600) | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | func GenerateKey() (*ecdsa.PrivateKey, error) { | 
					
						
							|  |  |  | 	return ecdsa.GenerateKey(S256(), rand.Reader) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-01 20:27:20 +02:00
										 |  |  | func ValidateSignatureValues(v byte, r, s *big.Int) bool { | 
					
						
							|  |  |  | 	vint := uint32(v) | 
					
						
							|  |  |  | 	if r.Cmp(common.Big0) == 0 || s.Cmp(common.Big0) == 0 { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.Cmp(secp256k1n) < 0 && s.Cmp(secp256k1n) < 0 && (vint == 27 || vint == 28) { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-05 19:31:18 +02:00
										 |  |  | func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { | 
					
						
							|  |  |  | 	s, err := Ecrecover(hash, sig) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2015-03-29 15:02:49 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-29 15:02:49 +02:00
										 |  |  | 	x, y := elliptic.Unmarshal(S256(), s) | 
					
						
							| 
									
										
										
										
											2015-04-05 19:31:18 +02:00
										 |  |  | 	return &ecdsa.PublicKey{S256(), x, y}, nil | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) { | 
					
						
							| 
									
										
										
										
											2015-01-22 18:12:05 +01:00
										 |  |  | 	if len(hash) != 32 { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	sig, err = secp256k1.Sign(hash, common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8)) | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | func Encrypt(pub *ecdsa.PublicKey, message []byte) ([]byte, error) { | 
					
						
							|  |  |  | 	return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pub), message, nil, nil) | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 14:17:10 +01:00
										 |  |  | func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) { | 
					
						
							|  |  |  | 	key := ecies.ImportECDSA(prv) | 
					
						
							| 
									
										
										
										
											2014-12-10 00:03:21 +01:00
										 |  |  | 	return key.Decrypt(rand.Reader, ct, nil, nil) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-27 19:32:45 +02:00
										 |  |  | // Used only by block tests. | 
					
						
							|  |  |  | func ImportBlockTestKey(privKeyBytes []byte) error { | 
					
						
							| 
									
										
										
										
											2015-05-12 18:33:04 +02:00
										 |  |  | 	ks := NewKeyStorePassphrase(common.DefaultDataDir() + "/keystore") | 
					
						
							| 
									
										
										
										
											2015-04-27 19:32:45 +02:00
										 |  |  | 	ecKey := ToECDSA(privKeyBytes) | 
					
						
							|  |  |  | 	key := &Key{ | 
					
						
							|  |  |  | 		Id:         uuid.NewRandom(), | 
					
						
							| 
									
										
										
										
											2015-06-04 16:52:23 +02:00
										 |  |  | 		Address:    PubkeyToAddress(ecKey.PublicKey), | 
					
						
							| 
									
										
										
										
											2015-04-27 19:32:45 +02:00
										 |  |  | 		PrivateKey: ecKey, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err := ks.StoreKey(key, "") | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | // 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 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-28 05:12:57 +01:00
										 |  |  | 	key.Id = uuid.NewRandom() | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2015-01-21 19:08:05 +01:00
										 |  |  | 	plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	ethPriv := Sha3(plainText) | 
					
						
							|  |  |  | 	ecKey := ToECDSA(ethPriv) | 
					
						
							|  |  |  | 	key = &Key{ | 
					
						
							|  |  |  | 		Id:         nil, | 
					
						
							| 
									
										
										
										
											2015-06-04 16:52:23 +02:00
										 |  |  | 		Address:    PubkeyToAddress(ecKey.PublicKey), | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 		PrivateKey: ecKey, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 	derivedAddr := hex.EncodeToString(key.Address.Bytes()) // needed because .Hex() gives leading "0x" | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	expectedAddr := preSaleKeyStruct.EthAddr | 
					
						
							|  |  |  | 	if derivedAddr != expectedAddr { | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 		err = errors.New(fmt.Sprintf("decrypted addr not equal to expected addr ", derivedAddr, expectedAddr)) | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return key, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | // AES-128 is selected due to size of encryptKey | 
					
						
							|  |  |  | func aesCTRXOR(key, inText, iv []byte) ([]byte, error) { | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	aesBlock, err := aes.NewCipher(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	stream := cipher.NewCTR(aesBlock, iv) | 
					
						
							|  |  |  | 	outText := make([]byte, len(inText)) | 
					
						
							|  |  |  | 	stream.XORKeyStream(outText, inText) | 
					
						
							|  |  |  | 	return outText, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func aesCBCDecrypt(key, cipherText, iv []byte) ([]byte, error) { | 
					
						
							|  |  |  | 	aesBlock, err := aes.NewCipher(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	decrypter := cipher.NewCBCDecrypter(aesBlock, iv) | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 	paddedPlaintext := make([]byte, len(cipherText)) | 
					
						
							|  |  |  | 	decrypter.CryptBlocks(paddedPlaintext, cipherText) | 
					
						
							|  |  |  | 	plaintext := PKCS7Unpad(paddedPlaintext) | 
					
						
							|  |  |  | 	if plaintext == nil { | 
					
						
							| 
									
										
										
										
											2015-04-02 18:15:58 +02:00
										 |  |  | 		err = errors.New("Decryption failed: PKCS7Unpad failed after AES decryption") | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 	return plaintext, err | 
					
						
							| 
									
										
										
										
											2015-01-20 23:55:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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)] | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-04 16:52:23 +02:00
										 |  |  | func PubkeyToAddress(p ecdsa.PublicKey) common.Address { | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	pubBytes := FromECDSAPub(&p) | 
					
						
							| 
									
										
										
										
											2015-06-04 16:52:23 +02:00
										 |  |  | 	return common.BytesToAddress(Sha3(pubBytes[1:])[12:]) | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | } |