OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-crypto / keys / types.go
1 package keys
2
3 import (
4         "fmt"
5         "sort"
6
7         crypto "github.com/tendermint/go-crypto"
8         wire "github.com/tendermint/go-wire"
9         data "github.com/tendermint/go-wire/data"
10 )
11
12 // Storage has many implementation, based on security and sharing requirements
13 // like disk-backed, mem-backed, vault, db, etc.
14 type Storage interface {
15         Put(name string, key []byte, info Info) error
16         Get(name string) (key []byte, info Info, err error)
17         List() (Infos, error)
18         Delete(name string) error
19 }
20
21 // Info is the public information about a key
22 type Info struct {
23         Name    string        `json:"name"`
24         Address data.Bytes    `json:"address"`
25         PubKey  crypto.PubKey `json:"pubkey"`
26 }
27
28 func (i *Info) Format() Info {
29         if !i.PubKey.Empty() {
30                 i.Address = i.PubKey.Address()
31         }
32         return *i
33 }
34
35 // Infos is a wrapper to allows alphabetical sorting of the keys
36 type Infos []Info
37
38 func (k Infos) Len() int           { return len(k) }
39 func (k Infos) Less(i, j int) bool { return k[i].Name < k[j].Name }
40 func (k Infos) Swap(i, j int)      { k[i], k[j] = k[j], k[i] }
41 func (k Infos) Sort() {
42         if k != nil {
43                 sort.Sort(k)
44         }
45 }
46
47 // Signable represents any transaction we wish to send to tendermint core
48 // These methods allow us to sign arbitrary Tx with the KeyStore
49 type Signable interface {
50         // SignBytes is the immutable data, which needs to be signed
51         SignBytes() []byte
52
53         // Sign will add a signature and pubkey.
54         //
55         // Depending on the Signable, one may be able to call this multiple times for multisig
56         // Returns error if called with invalid data or too many times
57         Sign(pubkey crypto.PubKey, sig crypto.Signature) error
58
59         // Signers will return the public key(s) that signed if the signature
60         // is valid, or an error if there is any issue with the signature,
61         // including if there are no signatures
62         Signers() ([]crypto.PubKey, error)
63
64         // TxBytes returns the transaction data as well as all signatures
65         // It should return an error if Sign was never called
66         TxBytes() ([]byte, error)
67 }
68
69 // Signer allows one to use a keystore to sign transactions
70 type Signer interface {
71         Sign(name, passphrase string, tx Signable) error
72 }
73
74 // Manager allows simple CRUD on a keystore, as an aid to signing
75 type Manager interface {
76         Signer
77         // Create also returns a seed phrase for cold-storage
78         Create(name, passphrase, algo string) (Info, string, error)
79         // Recover takes a seedphrase and loads in the private key
80         Recover(name, passphrase, seedphrase string) (Info, error)
81         List() (Infos, error)
82         Get(name string) (Info, error)
83         Update(name, oldpass, newpass string) error
84         Delete(name, passphrase string) error
85 }
86
87 /**** MockSignable allows us to view data ***/
88
89 // MockSignable lets us wrap arbitrary data with a go-crypto signature
90 type MockSignable struct {
91         Data      []byte
92         PubKey    crypto.PubKey
93         Signature crypto.Signature
94 }
95
96 var _ Signable = &MockSignable{}
97
98 // NewMockSignable sets the data to sign
99 func NewMockSignable(data []byte) *MockSignable {
100         return &MockSignable{Data: data}
101 }
102
103 // TxBytes returns the full data with signatures
104 func (s *MockSignable) TxBytes() ([]byte, error) {
105         return wire.BinaryBytes(s), nil
106 }
107
108 // SignBytes returns the original data passed into `NewSig`
109 func (s *MockSignable) SignBytes() []byte {
110         return s.Data
111 }
112
113 // Sign will add a signature and pubkey.
114 //
115 // Depending on the Signable, one may be able to call this multiple times for multisig
116 // Returns error if called with invalid data or too many times
117 func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
118         s.PubKey = pubkey
119         s.Signature = sig
120         return nil
121 }
122
123 // Signers will return the public key(s) that signed if the signature
124 // is valid, or an error if there is any issue with the signature,
125 // including if there are no signatures
126 func (s *MockSignable) Signers() ([]crypto.PubKey, error) {
127         if s.PubKey.Empty() {
128                 return nil, fmt.Errorf("no signers")
129         }
130         if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) {
131                 return nil, fmt.Errorf("invalid signature")
132         }
133         return []crypto.PubKey{s.PubKey}, nil
134 }