-
Notifications
You must be signed in to change notification settings - Fork 1
/
create.go
121 lines (98 loc) · 3.68 KB
/
create.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
package keys
import (
"bufio"
"crypto/rand"
"crypto/subtle"
"fmt"
"os"
"github.com/consensus-network/consensusd/cmd/consensuswallet/libconsensuswallet"
"github.com/consensus-network/consensusd/cmd/consensuswallet/utils"
"github.com/consensus-network/consensusd/domain/dagconfig"
"github.com/pkg/errors"
"github.com/tyler-smith/go-bip39"
)
// CreateMnemonics generates `numKeys` number of mnemonics.
func CreateMnemonics(params *dagconfig.Params, numKeys uint32, cmdLinePassword string, isMultisig bool, version uint32) (encryptedPrivateKeys []*EncryptedMnemonic, extendedPublicKeys []string, err error) {
mnemonics := make([]string, numKeys)
for i := uint32(0); i < numKeys; i++ {
var err error
mnemonics[i], err = libconsensuswallet.CreateMnemonic()
if err != nil {
return nil, nil, err
}
}
return encryptedMnemonicExtendedPublicKeyPairs(params, mnemonics, cmdLinePassword, isMultisig, version)
}
// ImportMnemonics imports a `numKeys` of mnemonics.
func ImportMnemonics(params *dagconfig.Params, numKeys uint32, cmdLinePassword string, isMultisig bool, version uint32) (encryptedPrivateKeys []*EncryptedMnemonic, extendedPublicKeys []string, err error) {
mnemonics := make([]string, numKeys)
for i := uint32(0); i < numKeys; i++ {
fmt.Printf("Enter mnemonic #%d here:\n", i+1)
reader := bufio.NewReader(os.Stdin)
mnemonic, err := utils.ReadLine(reader)
if err != nil {
return nil, nil, err
}
if !bip39.IsMnemonicValid(string(mnemonic)) {
return nil, nil, errors.Errorf("mnemonic is invalid")
}
mnemonics[i] = string(mnemonic)
}
return encryptedMnemonicExtendedPublicKeyPairs(params, mnemonics, cmdLinePassword, isMultisig, version)
}
func encryptedMnemonicExtendedPublicKeyPairs(params *dagconfig.Params, mnemonics []string, cmdLinePassword string, isMultisig bool, version uint32) (
encryptedPrivateKeys []*EncryptedMnemonic, extendedPublicKeys []string, err error) {
password := []byte(cmdLinePassword)
if len(password) == 0 {
password = []byte(GetPassword("Enter password for the key file:"))
confirmPassword := []byte(GetPassword("Confirm password:"))
if subtle.ConstantTimeCompare(password, confirmPassword) != 1 {
return nil, nil, errors.New("Passwords are not identical")
}
}
encryptedPrivateKeys = make([]*EncryptedMnemonic, 0, len(mnemonics))
extendedPublicKeys = make([]string, 0, len(mnemonics))
for _, mnemonic := range mnemonics {
extendedPublicKey, err := libconsensuswallet.MasterPublicKeyFromMnemonic(params, mnemonic, isMultisig, version)
if err != nil {
return nil, nil, err
}
extendedPublicKeys = append(extendedPublicKeys, extendedPublicKey)
encryptedPrivateKey, err := encryptMnemonic(mnemonic, password)
if err != nil {
return nil, nil, err
}
encryptedPrivateKeys = append(encryptedPrivateKeys, encryptedPrivateKey)
}
return encryptedPrivateKeys, extendedPublicKeys, nil
}
func generateSalt() ([]byte, error) {
salt := make([]byte, 16)
_, err := rand.Read(salt)
if err != nil {
return nil, err
}
return salt, nil
}
func encryptMnemonic(mnemonic string, password []byte) (*EncryptedMnemonic, error) {
mnemonicBytes := []byte(mnemonic)
salt, err := generateSalt()
if err != nil {
return nil, err
}
aead, err := getAEAD(defaultNumThreads, password, salt)
if err != nil {
return nil, err
}
// Select a random nonce, and leave capacity for the ciphertext.
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(mnemonicBytes)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
// Encrypt the message and append the ciphertext to the nonce.
cipher := aead.Seal(nonce, nonce, []byte(mnemonicBytes), nil)
return &EncryptedMnemonic{
cipher: cipher,
salt: salt,
}, nil
}