71 lines
2.1 KiB
Go
71 lines
2.1 KiB
Go
package tron
|
|
|
|
import (
|
|
"math/big"
|
|
|
|
"code.luxferre.top/luxferre/kisstron/bip32"
|
|
"code.luxferre.top/luxferre/kisstron/bip39"
|
|
"code.luxferre.top/luxferre/kisstron/secp256k1"
|
|
)
|
|
|
|
// ValidWordCount reports whether a mnemonic word count is supported.
|
|
func ValidWordCount(n int) bool {
|
|
return bip39.ValidWordCount(n)
|
|
}
|
|
|
|
// ValidateMnemonic reports whether a mnemonic is well-formed and checksum-correct.
|
|
func ValidateMnemonic(mnemonic string) bool {
|
|
return bip39.Validate(mnemonic)
|
|
}
|
|
|
|
// DeriveFromMnemonic restores a private key from a BIP-39 mnemonic and an
|
|
// optional passphrase using the given BIP-32 derivation path. An empty path
|
|
// selects the default TRON path (m/44'/195'/0'/0/0).
|
|
func DeriveFromMnemonic(mnemonic, passphrase, path string) (*PrivateKey, error) {
|
|
if path == "" {
|
|
path = bip32.DefaultPath
|
|
}
|
|
seed := bip39.Seed(mnemonic, passphrase)
|
|
key, err := bip32.DerivePath(seed, path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return newPrivateKeyUnchecked(key), nil
|
|
}
|
|
|
|
// GenerateWithMnemonic creates a brand new wallet and its mnemonic. The
|
|
// returned key and mnemonic belong together and must both be stored.
|
|
func GenerateWithMnemonic(passphrase string, numWords int, path string) (*PrivateKey, string, error) {
|
|
mnemonic, err := bip39.NewMnemonic(numWords)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
key, err := DeriveFromMnemonic(mnemonic, passphrase, path)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
return key, mnemonic, nil
|
|
}
|
|
|
|
// RecoverAddress recovers the signer's base58check address from a message hash
|
|
// and a 65-byte recoverable signature.
|
|
func RecoverAddress(hash, sig []byte) (string, error) {
|
|
if len(sig) != 65 {
|
|
return "", ErrBadSignature
|
|
}
|
|
r := new(big.Int).SetBytes(sig[0:32])
|
|
ss := new(big.Int).SetBytes(sig[32:64])
|
|
v := sig[64]
|
|
if v != 0 && v != 1 {
|
|
return "", ErrBadSignature
|
|
}
|
|
point, err := secp256k1.RecoverPublicKey(hash, &secp256k1.Signature{R: r, S: ss, V: v})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
raw := make([]byte, 64)
|
|
point.X.FillBytes(raw[0:32])
|
|
point.Y.FillBytes(raw[32:64])
|
|
return (&PublicKey{raw: raw}).ToBase58CheckAddress(), nil
|
|
}
|