-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaccount.go
153 lines (127 loc) · 3.15 KB
/
account.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
package hackSDK
import (
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
"crypto/elliptic"
crand "crypto/rand"
"crypto/sha256"
"fmt"
"golang.org/x/crypto/sha3"
"io"
"sync"
"github.com/btcsuite/btcd/btcec"
)
type OgAccount struct {
PrivateKey string
PublicKey string
Address string
}
func newAccount(privHex string) (*OgAccount, error) {
priv, err := HexToBytes(privHex)
if err != nil {
return nil, fmt.Errorf("decode hex private error: %v", err)
}
_, ecdsapub := btcec.PrivKeyFromBytes(btcec.S256(), priv)
pub := FromECDSAPub((*ecdsa.PublicKey)(ecdsapub))
addr := keccak256(pub[1:])[12:]
a := OgAccount{}
a.PrivateKey = fmt.Sprintf("%x", priv)
a.PublicKey = fmt.Sprintf("%x", pub)
a.Address = fmt.Sprintf("%x", addr)
return &a, nil
}
func GenerateAccount() OgAccount {
priv, pub := randomKeyPair()
a := OgAccount{}
a.PrivateKey = fmt.Sprintf("%x", priv)
a.PublicKey = fmt.Sprintf("%x", pub)
a.Address = fmt.Sprintf("%x", keccak256(pub)[12:])
return a
}
func randomKeyPair() (priv, pub []byte) {
privBytes := [32]byte{}
copy(privBytes[:], cRandBytes(32))
priv = privBytes[:]
_, ecdsapub := btcec.PrivKeyFromBytes(btcec.S256(), priv)
pub = FromECDSAPub((*ecdsa.PublicKey)(ecdsapub))
return priv, pub
}
func cRandBytes(numBytes int) []byte {
gRandInfo := &randInfo{}
gRandInfo.MixEntropy(RandBytes(32))
b := make([]byte, numBytes)
_, err := gRandInfo.Read(b)
if err != nil {
panic(err)
}
return b
}
type randInfo struct {
mtx sync.Mutex
seedBytes [32]byte
cipherAES256 cipher.Block
streamAES256 cipher.Stream
reader io.Reader
}
func (ri *randInfo) MixEntropy(seedBytes []byte) {
ri.mtx.Lock()
defer ri.mtx.Unlock()
// Make new ri.seedBytes
hashBytes := Sha256(seedBytes)
hashBytes32 := [32]byte{}
copy(hashBytes32[:], hashBytes)
ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32)
// Create new cipher.Block
var err error
ri.cipherAES256, err = aes.NewCipher(ri.seedBytes[:])
if err != nil {
panic("Error creating AES256 cipher: " + err.Error())
}
// Create new stream
ri.streamAES256 = cipher.NewCTR(ri.cipherAES256, RandBytes(aes.BlockSize))
// Create new reader
ri.reader = &cipher.StreamReader{S: ri.streamAES256, R: crand.Reader}
}
func (ri *randInfo) Read(b []byte) (n int, err error) {
ri.mtx.Lock()
defer ri.mtx.Unlock()
return ri.reader.Read(b)
}
func xorBytes32(bytesA [32]byte, bytesB [32]byte) (res [32]byte) {
for i, b := range bytesA {
res[i] = b ^ bytesB[i]
}
return res
}
func Sha256(bytes []byte) []byte {
hasher := sha256.New()
hasher.Write(bytes)
return hasher.Sum(nil)
}
func RandBytes(numBytes int) []byte {
b := make([]byte, numBytes)
_, err := crand.Read(b)
if err != nil {
panic(err)
}
return b
}
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil
}
return elliptic.Marshal(s256(), pub.X, pub.Y)
}
// s256 returns an instance of the secp256k1 curve.
func s256() elliptic.Curve {
return btcec.S256()
}
// keccak256 calculates and returns the keccak256 hash of the input data.
func keccak256(data ...[]byte) []byte {
d := sha3.NewLegacyKeccak256()
for _, b := range data {
d.Write(b)
}
return d.Sum(nil)
}