mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Implement importing private keys into the wallet (#1655)
* Implement importing private keys into the wallet. * Fix bad --import default. * Fix typo in --import annotation. * Make go lint happy. * Make go lint happier. Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
a795a9e619
commit
73b36f12f0
@ -25,8 +25,9 @@ type configFlags struct {
|
||||
type createConfig struct {
|
||||
KeysFile string `long:"keys-file" short:"f" description:"Keys file location (default: ~/.kaspawallet/keys.json (*nix), %USERPROFILE%\\AppData\\Local\\Kaspawallet\\key.json (Windows))"`
|
||||
MinimumSignatures uint32 `long:"min-signatures" short:"m" description:"Minimum required signatures" default:"1"`
|
||||
NumPrivateKeys uint32 `long:"num-private-keys" short:"k" description:"Number of private keys to generate" default:"1"`
|
||||
NumPrivateKeys uint32 `long:"num-private-keys" short:"k" description:"Number of private keys" default:"1"`
|
||||
NumPublicKeys uint32 `long:"num-public-keys" short:"n" description:"Total number of keys" default:"1"`
|
||||
Import bool `long:"import" short:"i" description:"Import private keys (as opposed to generating them)"`
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,14 @@ import (
|
||||
)
|
||||
|
||||
func create(conf *createConfig) error {
|
||||
encryptedPrivateKeys, publicKeys, err := keys.CreateKeyPairs(conf.NumPrivateKeys)
|
||||
var encryptedPrivateKeys []*keys.EncryptedPrivateKey
|
||||
var publicKeys [][]byte
|
||||
var err error
|
||||
if !conf.Import {
|
||||
encryptedPrivateKeys, publicKeys, err = keys.CreateKeyPairs(conf.NumPrivateKeys)
|
||||
} else {
|
||||
encryptedPrivateKeys, publicKeys, err = keys.ImportKeyPairs(conf.NumPrivateKeys)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,14 +1,41 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
// CreateKeyPairs generates `numKeys` number of key pairs.
|
||||
func CreateKeyPairs(numKeys uint32) (encryptedPrivateKeys []*EncryptedPrivateKey, publicKeys [][]byte, err error) {
|
||||
return createKeyPairsFromFunction(numKeys, func(_ uint32) ([]byte, []byte, error) {
|
||||
return libkaspawallet.CreateKeyPair()
|
||||
})
|
||||
}
|
||||
|
||||
// ImportKeyPairs imports a `numKeys` of private keys and generates key pairs out of them.
|
||||
func ImportKeyPairs(numKeys uint32) (encryptedPrivateKeys []*EncryptedPrivateKey, publicKeys [][]byte, err error) {
|
||||
return createKeyPairsFromFunction(numKeys, func(keyIndex uint32) ([]byte, []byte, error) {
|
||||
fmt.Printf("Enter private key #%d here:\n", keyIndex+1)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
line, isPrefix, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if isPrefix {
|
||||
return nil, nil, errors.Errorf("Private key is too long")
|
||||
}
|
||||
return libkaspawallet.KeyPairFromPrivateKeyHex(string(line))
|
||||
})
|
||||
}
|
||||
|
||||
func createKeyPairsFromFunction(numKeys uint32, keyPairFunction func(keyIndex uint32) ([]byte, []byte, error)) (
|
||||
encryptedPrivateKeys []*EncryptedPrivateKey, publicKeys [][]byte, err error) {
|
||||
|
||||
password := getPassword("Enter password for the key file:")
|
||||
confirmPassword := getPassword("Confirm password:")
|
||||
|
||||
@ -18,7 +45,7 @@ func CreateKeyPairs(numKeys uint32) (encryptedPrivateKeys []*EncryptedPrivateKey
|
||||
|
||||
encryptedPrivateKeys = make([]*EncryptedPrivateKey, 0, numKeys)
|
||||
for i := uint32(0); i < numKeys; i++ {
|
||||
privateKey, publicKey, err := libkaspawallet.CreateKeyPair()
|
||||
privateKey, publicKey, err := keyPairFunction(i)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package libkaspawallet
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"github.com/kaspanet/go-secp256k1"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
@ -13,7 +14,24 @@ func CreateKeyPair() ([]byte, []byte, error) {
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "Failed to generate private key")
|
||||
}
|
||||
publicKey, err := privateKey.SchnorrPublicKey()
|
||||
return keyPairBytes(privateKey)
|
||||
}
|
||||
|
||||
// KeyPairFromPrivateKeyHex decodes a private-public key pair out of `privateKeyHex`
|
||||
func KeyPairFromPrivateKeyHex(privateKeyHex string) ([]byte, []byte, error) {
|
||||
privateKeyBytes, err := hex.DecodeString(privateKeyHex)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "Failed to deserialized private key")
|
||||
}
|
||||
privateKey, err := secp256k1.DeserializeSchnorrPrivateKeyFromSlice(privateKeyBytes)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "Failed to deserialized private key")
|
||||
}
|
||||
return keyPairBytes(privateKey)
|
||||
}
|
||||
|
||||
func keyPairBytes(keyPair *secp256k1.SchnorrKeyPair) ([]byte, []byte, error) {
|
||||
publicKey, err := keyPair.SchnorrPublicKey()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "Failed to generate public key")
|
||||
}
|
||||
@ -22,7 +40,7 @@ func CreateKeyPair() ([]byte, []byte, error) {
|
||||
return nil, nil, errors.Wrap(err, "Failed to serialize public key")
|
||||
}
|
||||
|
||||
return privateKey.SerializePrivateKey()[:], publicKeySerialized[:], nil
|
||||
return keyPair.SerializePrivateKey()[:], publicKeySerialized[:], nil
|
||||
}
|
||||
|
||||
func addressFromPublicKey(params *dagconfig.Params, publicKeySerialized []byte) (util.Address, error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user