package crypto import ( "fmt" "io/ioutil" "strings" "github.com/ethereum/go-ethereum/ethutil" ) 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") } if len(secret) != 0 { secrets = append(secrets, ethutil.Hex2Bytes(secret)) } } 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 }