-
Notifications
You must be signed in to change notification settings - Fork 345
/
crypto.go
181 lines (147 loc) · 3.67 KB
/
crypto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package crypto
import (
"bytes"
"fmt"
"github.com/gnolang/gno/tm2/pkg/bech32"
"github.com/gnolang/gno/tm2/pkg/crypto/tmhash"
)
// ----------------------------------------
// Bech32Address
type Bech32Address string
func (b32 Bech32Address) String() string {
return string(b32)
}
// ----------------------------------------
// Address
const (
// AddressSize is the size of a pubkey address.
AddressSize = tmhash.TruncatedSize
)
// (truncated) hash of some preimage (typically of a pubkey).
type Address [AddressSize]byte
func AddressFromString(str string) (addr Address, err error) {
err = addr.DecodeString(str)
return
}
func MustAddressFromString(str string) (addr Address) {
err := addr.DecodeString(str)
if err != nil {
panic(fmt.Errorf("invalid address string representation: %v, error: %w", str, err))
}
return
}
func AddressFromPreimage(bz []byte) Address {
return AddressFromBytes(tmhash.SumTruncated(bz))
}
func AddressFromBytes(bz []byte) (ret Address) {
if len(bz) != AddressSize {
panic(fmt.Errorf("unexpected address byte length. expected %v, got %v", AddressSize, len(bz)))
}
copy(ret[:], bz)
return
}
func (addr Address) MarshalAmino() (string, error) {
return AddressToBech32(addr), nil
}
func (addr *Address) UnmarshalAmino(b32str string) (err error) {
if b32str == "" {
return nil // leave addr as zero.
}
addr2, err := AddressFromBech32(b32str)
if err != nil {
return err
}
copy(addr[:], addr2[:])
return nil
}
func (addr Address) Compare(other Address) int {
bz1 := make([]byte, len(addr))
bz2 := make([]byte, len(other))
copy(bz1, addr[:])
copy(bz2, other[:])
return bytes.Compare(bz1, bz2)
}
func (addr Address) IsZero() bool {
return addr == Address{}
}
func (addr Address) String() string {
return AddressToBech32(addr)
}
func (addr Address) Bech32() Bech32Address {
return Bech32Address(AddressToBech32(addr))
}
func (addr Address) Bytes() []byte {
res := make([]byte, AddressSize)
copy(res, addr[:])
return res
}
func (addr *Address) DecodeString(str string) error {
pre, bz, err := bech32.Decode(str)
if err != nil {
return err
}
if pre != Bech32AddrPrefix {
return fmt.Errorf("unexpected bech32 prefix for address. expected %q, got %q", Bech32AddrPrefix, pre)
}
if len(bz) != AddressSize {
return fmt.Errorf("unexpected address byte length. expected %v, got %v", AddressSize, len(bz))
}
copy((*addr)[:], bz)
return nil
}
// ----------------------------------------
// ID
// The bech32 representation w/ bech32 prefix.
type ID string
func (id ID) IsZero() bool {
return id == ""
}
func (id ID) String() string {
return string(id)
}
func (id ID) Validate() error {
if id.IsZero() {
return fmt.Errorf("zero ID is invalid")
}
var addr Address
err := addr.DecodeID(id)
return err
}
func AddressFromID(id ID) (addr Address, err error) {
err = addr.DecodeString(string(id))
return
}
func (addr Address) ID() ID {
return ID(addr.String())
}
func (addr *Address) DecodeID(id ID) error {
return addr.DecodeString(string(id))
}
// ----------------------------------------
// PubKey
// All operations must be deterministic.
type PubKey interface {
// Stable
Address() Address
Bytes() []byte
VerifyBytes(msg []byte, sig []byte) bool
Equals(PubKey) bool
String() string
}
// ----------------------------------------
// PrivKey
// All operations must be deterministic.
type PrivKey interface {
// Stable
Bytes() []byte
Sign(msg []byte) ([]byte, error)
PubKey() PubKey
Equals(PrivKey) bool
}
// ----------------------------------------
// Symmetric
type Symmetric interface {
Keygen() []byte
Encrypt(plaintext []byte, secret []byte) (ciphertext []byte)
Decrypt(ciphertext []byte, secret []byte) (plaintext []byte, err error)
}