| 
									
										
										
										
											2014-10-31 12:37:43 +01:00
										 |  |  | package crypto | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2014-10-23 15:01:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type KeyRing struct { | 
					
						
							|  |  |  | 	keys []*KeyPair | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewKeyRing() *KeyRing { | 
					
						
							|  |  |  | 	return &KeyRing{} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) AddKeyPair(keyPair *KeyPair) { | 
					
						
							|  |  |  | 	k.keys = append(k.keys, keyPair) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) GetKeyPair(i int) *KeyPair { | 
					
						
							|  |  |  | 	if len(k.keys) > i { | 
					
						
							|  |  |  | 		return k.keys[i] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) Empty() bool { | 
					
						
							|  |  |  | 	return k.Len() == 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) Len() int { | 
					
						
							|  |  |  | 	return len(k.keys) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) Each(f func(*KeyPair)) { | 
					
						
							|  |  |  | 	for _, keyPair := range k.keys { | 
					
						
							|  |  |  | 		f(keyPair) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewGeneratedKeyRing(len int) *KeyRing { | 
					
						
							|  |  |  | 	keyRing := NewKeyRing() | 
					
						
							|  |  |  | 	for i := 0; i < len; i++ { | 
					
						
							|  |  |  | 		keyRing.AddKeyPair(GenerateNewKeyPair()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewKeyRingFromFile(secfile string) (*KeyRing, error) { | 
					
						
							|  |  |  | 	var content []byte | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	content, err = ioutil.ReadFile(secfile) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keyRing, err := NewKeyRingFromString(string(content)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewKeyRingFromString(content string) (*KeyRing, error) { | 
					
						
							|  |  |  | 	secretStrings := strings.Split(content, "\n") | 
					
						
							|  |  |  | 	var secrets [][]byte | 
					
						
							|  |  |  | 	for _, secretString := range secretStrings { | 
					
						
							|  |  |  | 		secret := secretString | 
					
						
							|  |  |  | 		words := strings.Split(secretString, " ") | 
					
						
							|  |  |  | 		if len(words) == 24 { | 
					
						
							|  |  |  | 			secret = MnemonicDecode(words) | 
					
						
							|  |  |  | 		} else if len(words) != 1 { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("Unrecognised key format") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-07-01 20:08:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if len(secret) != 0 { | 
					
						
							|  |  |  | 			secrets = append(secrets, ethutil.Hex2Bytes(secret)) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-01 20:08:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 	return NewKeyRingFromSecrets(secrets) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewKeyRingFromSecrets(secs [][]byte) (*KeyRing, error) { | 
					
						
							|  |  |  | 	keyRing := NewKeyRing() | 
					
						
							|  |  |  | 	for _, sec := range secs { | 
					
						
							|  |  |  | 		keyPair, err := NewKeyPairFromSec(sec) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		keyRing.AddKeyPair(keyPair) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewKeyRingFromBytes(data []byte) (*KeyRing, error) { | 
					
						
							|  |  |  | 	var secrets [][]byte | 
					
						
							|  |  |  | 	it := ethutil.NewValueFromBytes(data).NewIterator() | 
					
						
							|  |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		secret := it.Value().Bytes() | 
					
						
							|  |  |  | 		secrets = append(secrets, secret) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keyRing, err := NewKeyRingFromSecrets(secrets) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) RlpEncode() []byte { | 
					
						
							|  |  |  | 	return k.RlpValue().Encode() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyRing) RlpValue() *ethutil.Value { | 
					
						
							|  |  |  | 	v := ethutil.EmptyValue() | 
					
						
							|  |  |  | 	k.Each(func(keyPair *KeyPair) { | 
					
						
							|  |  |  | 		v.Append(keyPair.RlpValue()) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	return v | 
					
						
							|  |  |  | } |