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  }