soft_wallet

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2019 License: LGPL-3.0 Imports: 38 Imported by: 0

Documentation

Overview

copy form "btcutil/hdkeychain/extendedkey.go", delete some unused function and change some functions to adapt Dipperin

Index

Constants

View Source
const (
	// RecommendedSeedLen is the recommended length in bytes for a seed
	// to a master node.
	RecommendedSeedLen = 32 // 256 bits

	// HardenedKeyStart is the index at which a hardended key starts.  Each
	// extended key has 2^31 normal child keys and 2^31 hardned child keys.
	// Thus the range for normal child keys is [0, 2^31 - 1] and the range
	// for hardened child keys is [2^31, 2^32 - 1].
	HardenedKeyStart = 0x80000000 // 2^31

	// MinSeedBytes is the minimum number of bytes allowed for a seed to
	// a master node.
	MinSeedBytes = 16 // 128 bits

	// MaxSeedBytes is the maximum number of bytes allowed for a seed to
	// a master node.
	MaxSeedBytes = 64 // 512 bits

)
View Source
const (
	KDF string = "Scrypt"
	// StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB
	// memory and taking approximately 1s CPU time on a modern processor.
	WalletStandardScryptN = 1 << 18

	// StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB
	// memory and taking approximately 1s CPU time on a modern processor.
	WalletStandardScryptP = 1

	// LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB
	// memory and taking approximately 100ms CPU time on a modern processor.
	WalletLightScryptN = 1 << 12

	// LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB
	// memory and taking approximately 100ms CPU time on a modern processor.
	WalletLightScryptP = 6

	WalletscryptR      = 8
	WalletscryptDKLen  = 32
	WalletMacCipherLen = 32
)

default kdf parameter

View Source
const (
	SymmetricAlgType = "AES-256"
	SymmetricAlgMode = "CBC"
)

use AES-128-CBC

View Source
const (
	WalletEntropyLength = 256
	WalletDefaultPath   = "/tmp/CSWallet"
	WalletDefaultName   = "CSWallet"
)
View Source
const (
	CloseWallet = iota
	RestoreWallet
	EstablishWallet
)
View Source
const (
	// m / purpose' / coin_type' / account' / change / address_index
	DefaultDerivedPath       = "m/44'/709394'/0'/0"
	DefaultDerivedPathLength = 4
	DefaultAccountValue      = 0
	AccountValueIndex        = 2
	SyncAccountNumber        = 20
	AddressIndexStartValue   = 1
)

Variables

View Source
var (
	// ErrDeriveHardFromPublic describes an error in which the caller
	// attempted to derive a hardened extended key from a public key.
	ErrDeriveHardFromPublic = errors.New("cannot derive a hardened key " +
		"from a public key")

	// ErrDeriveBeyondMaxDepth describes an error in which the caller
	// has attempted to derive more than 255 keys from a root key.
	ErrDeriveBeyondMaxDepth = errors.New("cannot derive a key with more than " +
		"255 indices in its path")

	// ErrNotPrivExtKey describes an error in which the caller attempted
	// to extract a private key from a public extended key.
	ErrNotPrivExtKey = errors.New("unable to create private keys from a " +
		"public extended key")

	// ErrInvalidChild describes an error in which the child at a specific
	// index is invalid due to the derived key falling outside of the valid
	// range for secp256k1 private keys.  This error indicates the caller
	// should simply ignore the invalid child extended key at this index and
	// increment to the next index.
	ErrInvalidChild = errors.New("the extended key at this index is invalid")

	// ErrUnusableSeed describes an error in which the provided seed is not
	// usable due to the derived key falling outside of the valid range for
	// secp256k1 private keys.  This error indicates the caller must choose
	// another seed.
	ErrUnusableSeed = errors.New("unusable seed")

	// ErrInvalidSeedLen describes an error in which the provided seed or
	// seed length is not in the allowed range.
	ErrInvalidSeedLen = fmt.Errorf("seed length must be between %d and %d "+
		"bits", MinSeedBytes*8, MaxSeedBytes*8)

	// ErrBadChecksum describes an error in which the checksum encoded with
	// a serialized extended key does not match the calculated value.
	ErrBadChecksum = errors.New("bad extended key checksum")

	// ErrInvalidKeyLen describes an error in which the provided serialized
	// key is not the expected length.
	ErrInvalidKeyLen = errors.New("the provided serialized extended key " +
		"length is invalid")
)
View Source
var DipperinChainCfg = DPChainCfg{
	HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4},
	HDPublicKeyID:  [4]byte{0x04, 0x88, 0xb2, 0x1e},
}

Functions

func AesDecryptCBC

func AesDecryptCBC(iv []byte, key []byte, cipherText []byte) (plaintext []byte, err error)

AES CBC decryption

func AesEncryptCBC

func AesEncryptCBC(iv []byte, key []byte, plaintext []byte) (cipherText []byte, err error)

AES CBC encryption

func CheckDerivedPathValid

func CheckDerivedPathValid(path accounts.DerivationPath) (bool, error)

judging the legitimacy of derived paths

func CheckPassword

func CheckPassword(password string) (err error)

judge the wallet password

func CheckWalletPath

func CheckWalletPath(path string) (err error)

judge the incoming wallet path

func ClearSensitiveData

func ClearSensitiveData(sensitiveData interface{})

clear sensitive data

func DecryptWalletContent

func DecryptWalletContent(walletCipher WalletCipher, iv []byte, sysKey EncryptKey) (walletPlain []byte, err error)

Decrypt and verify wallet ciphertext data based on wallet ciphertext and derived encrypted key and mac key

func GenerateMnemonic

func GenerateMnemonic(bitSize int) (mnemonic string, err error)

generating mnemonic

func GenerateSeed

func GenerateSeed(length uint8) ([]byte, error)

GenerateSeed returns a cryptographically secure random seed that can be used as the input for the NewMaster function to generate a new master node.

The length is in bytes and it must be between 16 and 64 (128 to 512 bits). The recommended length is 32 (256 bits) as defined by the RecommendedSeedLen constant.

func GetAccountFromExtendedKey

func GetAccountFromExtendedKey(keyData *ExtendedKey) (account accounts.Account, err error)

Obtain account information based on the extended key

func Hash160

func Hash160(buf []byte) []byte

Hash160 calculates the hash ripemd160(sha256(b)).

func PathExists

func PathExists(path string) (bool, error)

determine if a file or directory exists

Types

type DPChainCfg

type DPChainCfg struct {
	HDPrivateKeyID [4]byte
	HDPublicKeyID  [4]byte
}

define dipperin s own chain configuration Currently, only the HD extended key ID is stored, which is used to populate the version field in the extended key when the master key is generated according to the seed. Can be used to distinguish which configuration of this extended key belongs to Dipperin

type EncryptKey

type EncryptKey struct {
	// contains filtered or unexported fields
}

encrypted keyData

func GenSymKeyFromPassword

func GenSymKeyFromPassword(password string, kdfPara KDFParameter) (sysKey EncryptKey, err error)

Derived encrypted key and mac key based on password and KDF parameters

type EncryptParameter

type EncryptParameter struct {
	SymmetricAlgorithm
	KDFParameter
}

encryption parameters

type ExtendedKey

type ExtendedKey struct {
	// contains filtered or unexported fields
}

ExtendedKey houses all the information needed to support a hierarchical deterministic extended key. See the package overview documentation for more details on how to use extended keys.

func NewExtendedKey

func NewExtendedKey(version, key, chainCode, parentFP []byte, depth uint8,
	childNum uint32, isPrivate bool) *ExtendedKey

NewExtendedKey returns a new instance of an extended key with the given fields. No error checking is performed here as it's only intended to be a convenience method used to create a populated struct. This function should only by used by applications that need to create custom ExtendedKeys. All other applications should just use NewMaster, Child, or Neuter.

func NewKeyFromString

func NewKeyFromString(key string) (*ExtendedKey, error)

NewKeyFromString returns a new extended key instance from a base58-encoded extended key.

func NewMaster

func NewMaster(seed []byte, net *DPChainCfg) (*ExtendedKey, error)

NewMaster creates a new master node for use in creating a hierarchical deterministic key chain. The seed must be between 128 and 512 bits and should be generated by a cryptographically secure random generation source.

NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed will derive to an unusable secret key. The ErrUnusable error will be returned if this should occur, so the caller must check for it and generate a new seed accordingly.

func (*ExtendedKey) Child

func (k *ExtendedKey) Child(i uint32) (*ExtendedKey, error)

Child returns a derived child extended key at the given index. When this extended key is a private extended key (as determined by the IsPrivate function), a private extended key will be derived. Otherwise, the derived extended key will be also be a public extended key.

When the index is greater to or equal than the HardenedKeyStart constant, the derived extended key will be a hardened extended key. It is only possible to derive a hardended extended key from a private extended key. Consequently, this function will return ErrDeriveHardFromPublic if a hardened child extended key is requested from a public extended key.

A hardened extended key is useful since, as previously mentioned, it requires a parent private extended key to derive. In other words, normal child extended public keys can be derived from a parent public extended key (no knowledge of the parent private key) whereas hardened extended keys may not be.

NOTE: There is an extremely small chance (< 1 in 2^127) the specific child index does not derive to a usable child. The ErrInvalidChild error will be returned if this should occur, and the caller is expected to ignore the invalid child and simply increment to the next index.

func (*ExtendedKey) Depth

func (k *ExtendedKey) Depth() uint8

Depth returns the current derivation level with respect to the root.

The root key has depth zero, and the field has a maximum of 255 due to how depth is serialized.

func (*ExtendedKey) ECPrivKey

func (k *ExtendedKey) ECPrivKey() (*btcec.PrivateKey, error)

ECPrivKey converts the extended key to a btcec private key and returns it. As you might imagine this is only possible if the extended key is a private extended key (as determined by the IsPrivate function). The ErrNotPrivExtKey error will be returned if this function is called on a public extended key.

func (*ExtendedKey) ECPubKey

func (k *ExtendedKey) ECPubKey() (*btcec.PublicKey, error)

ECPubKey converts the extended key to a btcec public key and returns it.

func (*ExtendedKey) IsPrivate

func (k *ExtendedKey) IsPrivate() bool

IsPrivate returns whether or not the extended key is a private extended key.

A private extended key can be used to derive both hardened and non-hardened child private and public extended keys. A public extended key can only be used to derive non-hardened child public extended keys.

func (*ExtendedKey) Neuter

func (k *ExtendedKey) Neuter() (*ExtendedKey, error)

Neuter returns a new extended public key from this extended private key. The same extended key will be returned unaltered if it is already an extended public key.

As the name implies, an extended public key does not have access to the private key, so it is not capable of signing transactions or deriving child extended private keys. However, it is capable of deriving further child extended public keys.

func (*ExtendedKey) ParentFingerprint

func (k *ExtendedKey) ParentFingerprint() uint32

ParentFingerprint returns a fingerprint of the parent extended key from which this one was derived.

func (*ExtendedKey) String

func (k *ExtendedKey) String() string

String returns the extended key as a human-readable base58-encoded string.

func (*ExtendedKey) Zero

func (k *ExtendedKey) Zero()

Zero manually clears all fields and bytes in the extended key. This can be used to explicitly clear key material from memory for enhanced security against memory scraping. This function only clears this particular key and not any children that have already been derived.

type ExtendedKeyJson

type ExtendedKeyJson struct {
	Key       []byte `json:"Key"`    // This will be the pubkey for extended pub keys
	PubKey    []byte `json:"PubKey"` // This will only be set for extended priv keys
	ChainCode []byte `json:"ChainCode"`
	Depth     uint8  `json:"Depth"`
	ParentFP  []byte `json:"ParentFP"`
	ChildNum  uint32 `json:"ChildNum"`
	Version   []byte `json:"Version"`
	IsPrivate bool   `json:"IsPrivate"`
}

type KDFParameter

type KDFParameter struct {
	KDF       string                 `json:"kdf"`
	KDFParams map[string]interface{} `json:"kdfparams"`
}

key derivation algorithm parameters

type SoftWallet

type SoftWallet struct {
	Identifier accounts.WalletIdentifier //Wallet identifier
	// contains filtered or unexported fields
}

func NewSoftWallet

func NewSoftWallet() (*SoftWallet, error)

func (*SoftWallet) Accounts

func (w *SoftWallet) Accounts() ([]accounts.Account, error)

get a list of accounts in your soft wallet

func (*SoftWallet) Close

func (w *SoftWallet) Close() error

close the soft wallet

func (*SoftWallet) Contains

func (w *SoftWallet) Contains(account accounts.Account) (bool, error)

determine if the soft wallet contains an account

func (*SoftWallet) Derive

func (w *SoftWallet) Derive(path accounts.DerivationPath, save bool) (accounts.Account, error)

Generate an account based on the input derived path and add it to SoftWallet

func (*SoftWallet) Establish

func (w *SoftWallet) Establish(path, name, password, passPhrase string) (string, error)

create a new soft wallet and return the mnemonic

func (*SoftWallet) Evaluate

func (w *SoftWallet) Evaluate(account accounts.Account, seed []byte) (index [32]byte, proof []byte, err error)

generate vrf proof using private key and seed

func (*SoftWallet) GetAddressNonce

func (w *SoftWallet) GetAddressNonce(address common.Address) (nonce uint64, err error)

func (*SoftWallet) GetPKFromAddress

func (w *SoftWallet) GetPKFromAddress(account accounts.Account) (*ecdsa.PublicKey, error)

func (*SoftWallet) GetSKFromAddress

func (w *SoftWallet) GetSKFromAddress(address common.Address) (*ecdsa.PrivateKey, error)

func (*SoftWallet) GetWalletIdentifier

func (w *SoftWallet) GetWalletIdentifier() (accounts.WalletIdentifier, error)

return the soft wallet identifier

func (*SoftWallet) Open

func (w *SoftWallet) Open(path, name, password string) error

open the soft wallet according to the password

func (*SoftWallet) PaddingAddressNonce

func (w *SoftWallet) PaddingAddressNonce(GetAddressRelatedInfo accounts.AddressInfoReader) (err error)

func (*SoftWallet) RestoreWallet

func (w *SoftWallet) RestoreWallet(path, name, password, passPhrase, mnemonic string, GetAddressRelatedInfo accounts.AddressInfoReader) (err error)

recover wallet based on mnemonic

func (*SoftWallet) SelfDerive

func (w *SoftWallet) SelfDerive(base accounts.DerivationPath) error

According to the base path, query the used account from the chain and add it to the wallet.

func (*SoftWallet) SetAddressNonce

func (w *SoftWallet) SetAddressNonce(address common.Address, nonce uint64) (err error)

add nonce when send transaction

func (*SoftWallet) SignHash

func (w *SoftWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error)

Sign the hash value with its corresponding private key based on the incoming account

func (*SoftWallet) SignTx

func (w *SoftWallet) SignTx(account accounts.Account, tx *model.Transaction, chainID *big.Int) (*model.Transaction, error)

Sign the transaction with its corresponding private key based on the incoming account

func (*SoftWallet) Status

func (w *SoftWallet) Status() (string, error)

return the soft wallet status

type SymmetricAlgorithm

type SymmetricAlgorithm struct {
	AlgType  string                    `json:"AlgType"`
	ModeType string                    `json:"ModeType"`
	IV       [symmetricEncryptLen]byte `json:"IV"`
}

symmetric encryption algorithm parameters

type WalletCipher

type WalletCipher struct {
	Cipher    string `json:"Cipher"`
	MacCipher string `json:"MacCipher"`
}

wallet cipher

func CalWalletCipher

func CalWalletCipher(walletInfo WalletInfo, iv []byte, sysKey EncryptKey) (walletCipher WalletCipher, err error)

calculate wallet cipher

func EncryptWalletContent

func EncryptWalletContent(walletPlain []byte, iv []byte, sysKey EncryptKey) (walletCipher WalletCipher, err error)

Encrypt wallet plaintext data based on wallet plaintext and derived encrypted key and mac key

type WalletFileContent

type WalletFileContent struct {
	WalletCipher
	EncryptParameter
}

wallet file content

type WalletInfo

type WalletInfo struct {
	Accounts   []accounts.Account                         // used account included in the wallet
	Paths      map[common.Address]accounts.DerivationPath // derived path of the account in the wallet
	ExtendKeys map[common.Address]ExtendedKey             //Key information corresponding to the account address in the wallet
	Balances   map[common.Address]*big.Int                //The balance corresponding to each account address in the wallet
	Nonce      map[common.Address]uint64                  //The nonce value corresponding to each account address in the wallet
	//the used largest index in wallet derivation path, the key is the changeValue to identify the derived path, and the value is the largest index used.
	DerivedPathIndex map[uint32]uint32
	Seed             []byte //Wallet seed
	// contains filtered or unexported fields
}

func NewHdWalletInfo

func NewHdWalletInfo() (info *WalletInfo)

func (*WalletInfo) GenerateKeyFromSeedAndPath

func (w *WalletInfo) GenerateKeyFromSeedAndPath(derivedPath string, index uint32) (derivedKey *ExtendedKey, Path accounts.DerivationPath, err error)

Generate a master key according to the seed. Then generate a key corresponding to the index on the specified derived path according to the master key

func (*WalletInfo) GetAddressNonce

func (w *WalletInfo) GetAddressNonce(address common.Address) (nonce uint64, err error)

func (*WalletInfo) HdWalletInfoDecodeJson

func (w *WalletInfo) HdWalletInfoDecodeJson(decodeData []byte) (err error)

wallet data json decoding interface

func (WalletInfo) HdWalletInfoEncodeJson

func (w WalletInfo) HdWalletInfoEncodeJson() (encodeData []byte, err error)

Json encode for HdWalletInfo, converts key to string type in map

func (*WalletInfo) PaddingAddressNonce

func (w *WalletInfo) PaddingAddressNonce(GetAddressRelatedInfo accounts.AddressInfoReader) (err error)

func (*WalletInfo) SetAddressNonce

func (w *WalletInfo) SetAddressNonce(address common.Address, nonce uint64) (err error)

add nonce when send transaction

type WalletInfoJson

type WalletInfoJson struct {
	Accounts         []accounts.Account                 `json:"accounts"`
	Paths            map[string]accounts.DerivationPath `json:"paths"`
	ExtendKeys       map[string]ExtendedKeyJson         `json:"extend_keys"`
	Balances         map[string]*big.Int                `json:"balances"`
	Nonce            map[string]uint64
	DerivedPathIndex map[uint32]uint32
	Seed             []byte `json:"seed"`
}

func NewHdWalletInfoJson

func NewHdWalletInfoJson() (jsonInfo *WalletInfoJson)

type WalletPlaintext

type WalletPlaintext struct {
	// contains filtered or unexported fields
}

wallet plaintext

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL