github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/crypto/key.go (about) 1 /* 2 This file is part of go-ethereum 3 4 go-ethereum is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 go-ethereum is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 /** 18 * @authors 19 * Gustav Simonsson <gustav.simonsson@gmail.com> 20 * @date 2015 21 * 22 */ 23 24 package crypto 25 26 import ( 27 "bytes" 28 "crypto/ecdsa" 29 "crypto/elliptic" 30 "encoding/json" 31 "io" 32 33 "code.google.com/p/go-uuid/uuid" 34 ) 35 36 type Key struct { 37 Id uuid.UUID // Version 4 "random" for unique id not derived from key data 38 // to simplify lookups we also store the address 39 Address []byte 40 // we only store privkey as pubkey/address can be derived from it 41 // privkey in this struct is always in plaintext 42 PrivateKey *ecdsa.PrivateKey 43 } 44 45 type plainKeyJSON struct { 46 Id []byte 47 Address []byte 48 PrivateKey []byte 49 } 50 51 type cipherJSON struct { 52 Salt []byte 53 IV []byte 54 CipherText []byte 55 } 56 57 type encryptedKeyJSON struct { 58 Id []byte 59 Address []byte 60 Crypto cipherJSON 61 } 62 63 func (k *Key) MarshalJSON() (j []byte, err error) { 64 jStruct := plainKeyJSON{ 65 k.Id, 66 k.Address, 67 FromECDSA(k.PrivateKey), 68 } 69 j, err = json.Marshal(jStruct) 70 return j, err 71 } 72 73 func (k *Key) UnmarshalJSON(j []byte) (err error) { 74 keyJSON := new(plainKeyJSON) 75 err = json.Unmarshal(j, &keyJSON) 76 if err != nil { 77 return err 78 } 79 80 u := new(uuid.UUID) 81 *u = keyJSON.Id 82 k.Id = *u 83 k.Address = keyJSON.Address 84 k.PrivateKey = ToECDSA(keyJSON.PrivateKey) 85 86 return err 87 } 88 89 func NewKey(rand io.Reader) *Key { 90 randBytes := make([]byte, 32) 91 _, err := rand.Read(randBytes) 92 if err != nil { 93 panic("key generation: could not read from random source: " + err.Error()) 94 } 95 reader := bytes.NewReader(randBytes) 96 _, x, y, err := elliptic.GenerateKey(S256(), reader) 97 if err != nil { 98 panic("key generation: elliptic.GenerateKey failed: " + err.Error()) 99 } 100 privateKeyMarshalled := elliptic.Marshal(S256(), x, y) 101 privateKeyECDSA := ToECDSA(privateKeyMarshalled) 102 103 id := uuid.NewRandom() 104 key := &Key{ 105 Id: id, 106 Address: PubkeyToAddress(privateKeyECDSA.PublicKey), 107 PrivateKey: privateKeyECDSA, 108 } 109 return key 110 }