| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | package crypto | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"crypto/ecdsa" | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-02-10 12:29:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-09-10 21:48:20 +06:00
										 |  |  | 	"github.com/pborman/uuid" | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 	version = 3 | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | type Key struct { | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	Id uuid.UUID // Version 4 "random" for unique id not derived from key data | 
					
						
							|  |  |  | 	// to simplify lookups we also store the address | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 	Address common.Address | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	// we only store privkey as pubkey/address can be derived from it | 
					
						
							|  |  |  | 	// privkey in this struct is always in plaintext | 
					
						
							|  |  |  | 	PrivateKey *ecdsa.PrivateKey | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | type plainKeyJSON struct { | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | 	Address    string `json:"address"` | 
					
						
							|  |  |  | 	PrivateKey string `json:"privatekey"` | 
					
						
							|  |  |  | 	Id         string `json:"id"` | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 	Version    int    `json:"version"` | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | type encryptedKeyJSONV3 struct { | 
					
						
							|  |  |  | 	Address string `json:"address"` | 
					
						
							|  |  |  | 	Crypto  cryptoJSON | 
					
						
							|  |  |  | 	Id      string `json:"id"` | 
					
						
							|  |  |  | 	Version int    `json:"version"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type encryptedKeyJSONV1 struct { | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | 	Address string `json:"address"` | 
					
						
							|  |  |  | 	Crypto  cryptoJSON | 
					
						
							|  |  |  | 	Id      string `json:"id"` | 
					
						
							|  |  |  | 	Version string `json:"version"` | 
					
						
							| 
									
										
										
										
											2015-04-15 13:24:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | type cryptoJSON struct { | 
					
						
							| 
									
										
										
										
											2015-05-24 03:42:10 +02:00
										 |  |  | 	Cipher       string                 `json:"cipher"` | 
					
						
							|  |  |  | 	CipherText   string                 `json:"ciphertext"` | 
					
						
							|  |  |  | 	CipherParams cipherparamsJSON       `json:"cipherparams"` | 
					
						
							|  |  |  | 	KDF          string                 `json:"kdf"` | 
					
						
							|  |  |  | 	KDFParams    map[string]interface{} `json:"kdfparams"` | 
					
						
							|  |  |  | 	MAC          string                 `json:"mac"` | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | type cipherparamsJSON struct { | 
					
						
							|  |  |  | 	IV string `json:"iv"` | 
					
						
							| 
									
										
										
										
											2015-04-15 13:24:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type scryptParamsJSON struct { | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | 	N     int    `json:"n"` | 
					
						
							|  |  |  | 	R     int    `json:"r"` | 
					
						
							|  |  |  | 	P     int    `json:"p"` | 
					
						
							|  |  |  | 	DkLen int    `json:"dklen"` | 
					
						
							|  |  |  | 	Salt  string `json:"salt"` | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *Key) MarshalJSON() (j []byte, err error) { | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	jStruct := plainKeyJSON{ | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 		hex.EncodeToString(k.Address[:]), | 
					
						
							|  |  |  | 		hex.EncodeToString(FromECDSA(k.PrivateKey)), | 
					
						
							| 
									
										
										
										
											2015-05-10 20:30:02 +02:00
										 |  |  | 		k.Id.String(), | 
					
						
							|  |  |  | 		version, | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	j, err = json.Marshal(jStruct) | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return j, err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *Key) UnmarshalJSON(j []byte) (err error) { | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	keyJSON := new(plainKeyJSON) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	err = json.Unmarshal(j, &keyJSON) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u := new(uuid.UUID) | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	*u = uuid.Parse(keyJSON.Id) | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	k.Id = *u | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	addr, err := hex.DecodeString(keyJSON.Address) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	privkey, err := hex.DecodeString(keyJSON.PrivateKey) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	k.Address = common.BytesToAddress(addr) | 
					
						
							|  |  |  | 	k.PrivateKey = ToECDSA(privkey) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | func NewKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key { | 
					
						
							|  |  |  | 	id := uuid.NewRandom() | 
					
						
							|  |  |  | 	key := &Key{ | 
					
						
							|  |  |  | 		Id:         id, | 
					
						
							| 
									
										
										
										
											2015-06-04 16:52:23 +02:00
										 |  |  | 		Address:    PubkeyToAddress(privateKeyECDSA.PublicKey), | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 		PrivateKey: privateKeyECDSA, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return key | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | func NewKey(rand io.Reader) *Key { | 
					
						
							| 
									
										
										
										
											2015-03-11 01:10:25 +01:00
										 |  |  | 	randBytes := make([]byte, 64) | 
					
						
							| 
									
										
										
										
											2015-01-19 20:24:30 +01:00
										 |  |  | 	_, err := rand.Read(randBytes) | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic("key generation: could not read from random source: " + err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	reader := bytes.NewReader(randBytes) | 
					
						
							| 
									
										
										
										
											2015-03-11 01:10:25 +01:00
										 |  |  | 	privateKeyECDSA, err := ecdsa.GenerateKey(S256(), reader) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-11 01:10:25 +01:00
										 |  |  | 		panic("key generation: ecdsa.GenerateKey failed: " + err.Error()) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	return NewKeyFromECDSA(privateKeyECDSA) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } |