forked from rubblelabs/ripple
/
hash.go
139 lines (114 loc) · 3.07 KB
/
hash.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
package crypto
import (
"fmt"
"math/big"
)
// First byte is the network
// Second byte is the version
// Remaining bytes are the payload
type hash []byte
func NewRippleHash(s string) (Hash, error) {
// Special case which will deal short addresses
switch s {
case "0":
return newHashFromString(ACCOUNT_ZERO)
case "1":
return newHashFromString(ACCOUNT_ONE)
default:
return newHashFromString(s)
}
}
// Checks hash matches expected version
func NewRippleHashCheck(s string, version HashVersion) (Hash, error) {
hash, err := NewRippleHash(s)
if err != nil {
return nil, err
}
if hash.Version() != version {
want := hashTypes[version].Description
got := hashTypes[hash.Version()].Description
return nil, fmt.Errorf("Bad version for: %s expected: %s got: %s ", s, want, got)
}
return hash, nil
}
func NewAccountId(b []byte) (Hash, error) {
return newHash(b, RIPPLE_ACCOUNT_ID)
}
func NewAccountPublicKey(b []byte) (Hash, error) {
return newHash(b, RIPPLE_ACCOUNT_PUBLIC)
}
func NewAccountPrivateKey(b []byte) (Hash, error) {
return newHash(b, RIPPLE_ACCOUNT_PRIVATE)
}
func NewNodePublicKey(b []byte) (Hash, error) {
return newHash(b, RIPPLE_NODE_PUBLIC)
}
func NewNodePrivateKey(b []byte) (Hash, error) {
return newHash(b, RIPPLE_NODE_PRIVATE)
}
func NewFamilySeed(b []byte) (Hash, error) {
return newHash(b, RIPPLE_FAMILY_SEED)
}
func AccountId(key Key, sequence *uint32) (Hash, error) {
return NewAccountId(key.Id(sequence))
}
func AccountPublicKey(key Key, sequence *uint32) (Hash, error) {
return NewAccountPublicKey(key.Public(sequence))
}
func AccountPrivateKey(key Key, sequence *uint32) (Hash, error) {
return NewAccountPrivateKey(key.Private(sequence))
}
func NodePublicKey(key Key) (Hash, error) {
return NewNodePublicKey(key.Public(nil))
}
func NodePrivateKey(key Key) (Hash, error) {
return NewNodePrivateKey(key.Private(nil))
}
func GenerateFamilySeed(password string) (Hash, error) {
return NewFamilySeed(Sha512Quarter([]byte(password)))
}
func newHash(b []byte, version HashVersion) (Hash, error) {
n := hashTypes[version].Payload
if len(b) > n {
return nil, fmt.Errorf("Hash is wrong size, expected: %d got: %d", n, len(b))
}
return append(hash{byte(version)}, b...), nil
}
func newHashFromString(s string) (Hash, error) {
decoded, err := Base58Decode(s, ALPHABET)
if err != nil {
return nil, err
}
return hash(decoded[:len(decoded)-4]), nil
}
func (h hash) String() string {
b := append(hash{byte(h.Version())}, h.Payload()...)
return Base58Encode(b, ALPHABET)
}
func (h hash) Version() HashVersion {
return HashVersion(h[0])
}
func (h hash) Payload() []byte {
return h[1:]
}
// Return a slice of the payload with leading zeroes omitted
func (h hash) PayloadTrimmed() []byte {
payload := h.Payload()
for i := range payload {
if payload[i] != 0 {
return payload[i:]
}
}
return payload[len(payload)-1:]
}
func (h hash) Value() *big.Int {
return big.NewInt(0).SetBytes(h.Payload())
}
func (h hash) MarshalText() ([]byte, error) {
return []byte(h.String()), nil
}
func (h hash) Clone() Hash {
c := make(hash, len(h))
copy(c, h)
return c
}