From 9ccdcaf74719a5fbae438fcff21dcb9598c95803 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 17 Feb 2018 15:08:21 -0800 Subject: [PATCH] lnwallet: update the SignDescriptor struct to use keychain.KeyDescriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, we update the SignDescriptor struct to instead use the keychain.KeyDescriptor struct inplace of a raw public key. We do this as this allows for a recovery mode, where the caller doesn’t know what key was used exactly, but remembers the precise KeyDescriptor. A stateless signer is still able to re-derive the proper key, as it’s given the full path. --- lnwallet/signdescriptor.go | 53 ++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/lnwallet/signdescriptor.go b/lnwallet/signdescriptor.go index f2057d2a..d1ae1834 100644 --- a/lnwallet/signdescriptor.go +++ b/lnwallet/signdescriptor.go @@ -5,6 +5,7 @@ import ( "errors" "io" + "github.com/lightningnetwork/lnd/keychain" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/txscript" "github.com/roasbeef/btcd/wire" @@ -20,10 +21,11 @@ var ( // a given output. This struct is used by the Signer interface in order to gain // access to critical data needed to generate a valid signature. type SignDescriptor struct { - // Pubkey is the public key to which the signature should be generated - // over. The Signer should then generate a signature with the private - // key corresponding to this public key. - PubKey *btcec.PublicKey + // KeyDesc is a descriptor that precisely describes *which* key to use + // for signing. This may provide the raw public key directly, or + // require the Signer to re-derive the key according to the populated + // derivation path. + KeyDesc keychain.KeyDescriptor // SingleTweak is a scalar value that will be added to the private key // corresponding to the above public key to obtain the private key to @@ -83,10 +85,26 @@ type SignDescriptor struct { // yet, since that is usually done just before broadcast by the witness // generator. func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error { - serializedPubKey := sd.PubKey.SerializeCompressed() - if err := wire.WriteVarBytes(w, 0, serializedPubKey); err != nil { + err := binary.Write(w, binary.BigEndian, sd.KeyDesc.Family) + if err != nil { return err } + err = binary.Write(w, binary.BigEndian, sd.KeyDesc.Index) + if err != nil { + return err + } + + err = binary.Write(w, binary.BigEndian, sd.KeyDesc.PubKey != nil) + if err != nil { + return err + } + + if sd.KeyDesc.PubKey != nil { + serializedPubKey := sd.KeyDesc.PubKey.SerializeCompressed() + if err := wire.WriteVarBytes(w, 0, serializedPubKey); err != nil { + return err + } + } if err := wire.WriteVarBytes(w, 0, sd.SingleTweak); err != nil { return err @@ -120,15 +138,34 @@ func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error { // ReadSignDescriptor deserializes a SignDescriptor struct from the passed // io.Reader stream. func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error { - pubKeyBytes, err := wire.ReadVarBytes(r, 0, 34, "pubkey") + err := binary.Read(r, binary.BigEndian, &sd.KeyDesc.Family) if err != nil { return err } - sd.PubKey, err = btcec.ParsePubKey(pubKeyBytes, btcec.S256()) + err = binary.Read(r, binary.BigEndian, &sd.KeyDesc.Index) if err != nil { return err } + var hasKey bool + err = binary.Read(r, binary.BigEndian, &hasKey) + if err != nil { + return err + } + + if hasKey { + pubKeyBytes, err := wire.ReadVarBytes(r, 0, 34, "pubkey") + if err != nil { + return err + } + sd.KeyDesc.PubKey, err = btcec.ParsePubKey( + pubKeyBytes, btcec.S256(), + ) + if err != nil { + return err + } + } + singleTweak, err := wire.ReadVarBytes(r, 0, 32, "singleTweak") if err != nil { return err