mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 09:50:08 +01:00
81 lines
2.5 KiB
Go
81 lines
2.5 KiB
Go
package psbt
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
)
|
|
|
|
// Bip32Derivation encapsulates the data for the input and output
|
|
// Bip32Derivation key-value fields.
|
|
//
|
|
// TODO(roasbeef): use hdkeychain here instead?
|
|
type Bip32Derivation struct {
|
|
// PubKey is the raw pubkey serialized in compressed format.
|
|
PubKey []byte
|
|
|
|
// MasterKeyFingerprint is the fingerprint of the master pubkey.
|
|
MasterKeyFingerprint uint32
|
|
|
|
// Bip32Path is the BIP 32 path with child index as a distinct integer.
|
|
Bip32Path []uint32
|
|
}
|
|
|
|
// checkValid ensures that the PubKey in the Bip32Derivation struct is valid.
|
|
func (pb *Bip32Derivation) checkValid() bool {
|
|
return validatePubkey(pb.PubKey)
|
|
}
|
|
|
|
// Bip32Sorter implements sort.Interface for the Bip32Derivation struct.
|
|
type Bip32Sorter []*Bip32Derivation
|
|
|
|
func (s Bip32Sorter) Len() int { return len(s) }
|
|
|
|
func (s Bip32Sorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
|
|
func (s Bip32Sorter) Less(i, j int) bool {
|
|
return bytes.Compare(s[i].PubKey, s[j].PubKey) < 0
|
|
}
|
|
|
|
// ReadBip32Derivation deserializes a byte slice containing chunks of 4 byte
|
|
// little endian encodings of uint32 values, the first of which is the
|
|
// masterkeyfingerprint and the remainder of which are the derivation path.
|
|
func ReadBip32Derivation(path []byte) (uint32, []uint32, error) {
|
|
// BIP-0174 defines the derivation path being encoded as
|
|
// "<32-bit uint> <32-bit uint>*"
|
|
// with the asterisk meaning 0 to n times. Which in turn means that an
|
|
// empty path is valid, only the key fingerprint is mandatory.
|
|
if len(path)%4 != 0 {
|
|
return 0, nil, ErrInvalidPsbtFormat
|
|
}
|
|
|
|
masterKeyInt := binary.LittleEndian.Uint32(path[:4])
|
|
|
|
var paths []uint32
|
|
for i := 4; i < len(path); i += 4 {
|
|
paths = append(paths, binary.LittleEndian.Uint32(path[i:i+4]))
|
|
}
|
|
|
|
return masterKeyInt, paths, nil
|
|
}
|
|
|
|
// SerializeBIP32Derivation takes a master key fingerprint as defined in BIP32,
|
|
// along with a path specified as a list of uint32 values, and returns a
|
|
// bytestring specifying the derivation in the format required by BIP174: //
|
|
// master key fingerprint (4) || child index (4) || child index (4) || ....
|
|
func SerializeBIP32Derivation(masterKeyFingerprint uint32,
|
|
bip32Path []uint32) []byte {
|
|
|
|
var masterKeyBytes [4]byte
|
|
binary.LittleEndian.PutUint32(masterKeyBytes[:], masterKeyFingerprint)
|
|
|
|
derivationPath := make([]byte, 0, 4+4*len(bip32Path))
|
|
derivationPath = append(derivationPath, masterKeyBytes[:]...)
|
|
for _, path := range bip32Path {
|
|
var pathbytes [4]byte
|
|
binary.LittleEndian.PutUint32(pathbytes[:], path)
|
|
derivationPath = append(derivationPath, pathbytes[:]...)
|
|
}
|
|
|
|
return derivationPath
|
|
}
|