mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
lnwallet: move latest SignDescriptor + serialization
This commit is contained in:
parent
b7e426ecdc
commit
438c6b9621
3 changed files with 72 additions and 77 deletions
|
@ -224,66 +224,6 @@ type BlockChainIO interface {
|
||||||
GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error)
|
GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignDescriptor houses the necessary information required to successfully sign
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// be used to sign this input. This value is typically derived via the
|
|
||||||
// following computation:
|
|
||||||
//
|
|
||||||
// * derivedKey = privkey + sha256(perCommitmentPoint || pubKey) mod N
|
|
||||||
//
|
|
||||||
// NOTE: If this value is nil, then the input can be signed using only
|
|
||||||
// the above public key. Either a SingleTweak should be set or a
|
|
||||||
// DoubleTweak, not both.
|
|
||||||
SingleTweak []byte
|
|
||||||
|
|
||||||
// DoubleTweak is a private key that will be used in combination with
|
|
||||||
// its corresponding private key to derive the private key that is to
|
|
||||||
// be used to sign the target input. Within the Lightning protocol,
|
|
||||||
// this value is typically the commitment secret from a previously
|
|
||||||
// revoked commitment transaction. This value is in combination with
|
|
||||||
// two hash values, and the original private key to derive the private
|
|
||||||
// key to be used when signing.
|
|
||||||
//
|
|
||||||
// * k = (privKey*sha256(pubKey || tweakPub) +
|
|
||||||
// tweakPriv*sha256(tweakPub || pubKey)) mod N
|
|
||||||
//
|
|
||||||
// NOTE: If this value is nil, then the input can be signed using only
|
|
||||||
// the above public key. Either a SingleTweak should be set or a
|
|
||||||
// DoubleTweak, not both.
|
|
||||||
DoubleTweak *btcec.PrivateKey
|
|
||||||
|
|
||||||
// WitnessScript is the full script required to properly redeem the
|
|
||||||
// output. This field will only be populated if a p2wsh or a p2sh
|
|
||||||
// output is being signed.
|
|
||||||
WitnessScript []byte
|
|
||||||
|
|
||||||
// Output is the target output which should be signed. The PkScript and
|
|
||||||
// Value fields within the output should be properly populated,
|
|
||||||
// otherwise an invalid signature may be generated.
|
|
||||||
Output *wire.TxOut
|
|
||||||
|
|
||||||
// HashType is the target sighash type that should be used when
|
|
||||||
// generating the final sighash, and signature.
|
|
||||||
HashType txscript.SigHashType
|
|
||||||
|
|
||||||
// SigHashes is the pre-computed sighash midstate to be used when
|
|
||||||
// generating the final sighash for signing.
|
|
||||||
SigHashes *txscript.TxSigHashes
|
|
||||||
|
|
||||||
// InputIndex is the target input within the transaction that should be
|
|
||||||
// signed.
|
|
||||||
InputIndex int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signer represents an abstract object capable of generating raw signatures as
|
// Signer represents an abstract object capable of generating raw signatures as
|
||||||
// well as full complete input scripts given a valid SignDescriptor and
|
// well as full complete input scripts given a valid SignDescriptor and
|
||||||
// transaction. This interface fully abstracts away signing paving the way for
|
// transaction. This interface fully abstracts away signing paving the way for
|
||||||
|
|
|
@ -2,6 +2,7 @@ package lnwallet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
@ -10,6 +11,12 @@ import (
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrTweakOverdose signals a SignDescriptor is invalid because both of its
|
||||||
|
// SingleTweak and DoubleTweak are non-nil.
|
||||||
|
ErrTweakOverdose = errors.New("sign descriptor should only have one tweak")
|
||||||
|
)
|
||||||
|
|
||||||
// SignDescriptor houses the necessary information required to successfully sign
|
// SignDescriptor houses the necessary information required to successfully sign
|
||||||
// a given output. This struct is used by the Signer interface in order to gain
|
// 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.
|
// access to critical data needed to generate a valid signature.
|
||||||
|
@ -19,14 +26,33 @@ type SignDescriptor struct {
|
||||||
// key corresponding to this public key.
|
// key corresponding to this public key.
|
||||||
PubKey *btcec.PublicKey
|
PubKey *btcec.PublicKey
|
||||||
|
|
||||||
// PrivateTweak is a scalar value that should be added to the private
|
// SingleTweak is a scalar value that will be added to the private key
|
||||||
// key corresponding to the above public key to obtain the private key
|
// corresponding to the above public key to obtain the private key to
|
||||||
// to be used to sign this input. This value is typically a leaf node
|
// be used to sign this input. This value is typically derived via the
|
||||||
// from the revocation tree.
|
// following computation:
|
||||||
|
//
|
||||||
|
// * derivedKey = privkey + sha256(perCommitmentPoint || pubKey) mod N
|
||||||
//
|
//
|
||||||
// NOTE: If this value is nil, then the input can be signed using only
|
// NOTE: If this value is nil, then the input can be signed using only
|
||||||
// the above public key.
|
// the above public key. Either a SingleTweak should be set or a
|
||||||
PrivateTweak []byte
|
// DoubleTweak, not both.
|
||||||
|
SingleTweak []byte
|
||||||
|
|
||||||
|
// DoubleTweak is a private key that will be used in combination with
|
||||||
|
// its corresponding private key to derive the private key that is to
|
||||||
|
// be used to sign the target input. Within the Lightning protocol,
|
||||||
|
// this value is typically the commitment secret from a previously
|
||||||
|
// revoked commitment transaction. This value is in combination with
|
||||||
|
// two hash values, and the original private key to derive the private
|
||||||
|
// key to be used when signing.
|
||||||
|
//
|
||||||
|
// * k = (privKey*sha256(pubKey || tweakPub) +
|
||||||
|
// tweakPriv*sha256(tweakPub || pubKey)) mod N
|
||||||
|
//
|
||||||
|
// NOTE: If this value is nil, then the input can be signed using only
|
||||||
|
// the above public key. Either a SingleTweak should be set or a
|
||||||
|
// DoubleTweak, not both.
|
||||||
|
DoubleTweak *btcec.PrivateKey
|
||||||
|
|
||||||
// WitnessScript is the full script required to properly redeem the
|
// WitnessScript is the full script required to properly redeem the
|
||||||
// output. This field will only be populated if a p2wsh or a p2sh
|
// output. This field will only be populated if a p2wsh or a p2sh
|
||||||
|
@ -62,7 +88,15 @@ func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wire.WriteVarBytes(w, 0, sd.PrivateTweak); err != nil {
|
if err := wire.WriteVarBytes(w, 0, sd.SingleTweak); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var doubleTweakBytes []byte
|
||||||
|
if sd.DoubleTweak != nil {
|
||||||
|
doubleTweakBytes = sd.DoubleTweak.Serialize()
|
||||||
|
}
|
||||||
|
if err := wire.WriteVarBytes(w, 0, doubleTweakBytes); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,20 +130,41 @@ func ReadSignDescriptor(r io.Reader, sd *SignDescriptor) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privateTweak, err := wire.ReadVarBytes(r, 0, 32, "privateTweak")
|
singleTweak, err := wire.ReadVarBytes(r, 0, 32, "singleTweak")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serializing a SignDescriptor with a nil-valued PrivateTweak results in
|
// Serializing a SignDescriptor with a nil-valued SingleTweak results in
|
||||||
// deserializing a zero-length slice. Since a nil-valued PrivateTweak has
|
// deserializing a zero-length slice. Since a nil-valued SingleTweak has
|
||||||
// special meaning and a zero-length slice for a PrivateTweak is invalid,
|
// special meaning and a zero-length slice for a SingleTweak is invalid,
|
||||||
// we can use the zero-length slice as the flag for a nil-valued
|
// we can use the zero-length slice as the flag for a nil-valued
|
||||||
// PrivateTweak.
|
// SingleTweak.
|
||||||
if len(privateTweak) == 0 {
|
if len(singleTweak) == 0 {
|
||||||
sd.PrivateTweak = nil
|
sd.SingleTweak = nil
|
||||||
} else {
|
} else {
|
||||||
sd.PrivateTweak = privateTweak
|
sd.SingleTweak = singleTweak
|
||||||
|
}
|
||||||
|
|
||||||
|
doubleTweakBytes, err := wire.ReadVarBytes(r, 0, 32, "doubleTweak")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serializing a SignDescriptor with a nil-valued DoubleTweak results in
|
||||||
|
// deserializing a zero-length slice. Since a nil-valued DoubleTweak has
|
||||||
|
// special meaning and a zero-length slice for a DoubleTweak is invalid,
|
||||||
|
// we can use the zero-length slice as the flag for a nil-valued
|
||||||
|
// DoubleTweak.
|
||||||
|
if len(doubleTweakBytes) == 0 {
|
||||||
|
sd.DoubleTweak = nil
|
||||||
|
} else {
|
||||||
|
sd.DoubleTweak, _ = btcec.PrivKeyFromBytes(btcec.S256(), doubleTweakBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one tweak should ever be set, fail if both are present.
|
||||||
|
if sd.SingleTweak != nil && sd.DoubleTweak != nil {
|
||||||
|
return ErrTweakOverdose
|
||||||
}
|
}
|
||||||
|
|
||||||
witnessScript, err := wire.ReadVarBytes(r, 0, 100, "witnessScript")
|
witnessScript, err := wire.ReadVarBytes(r, 0, 100, "witnessScript")
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestSignDescriptorSerialization(t *testing.T) {
|
||||||
|
|
||||||
signDescriptors := []SignDescriptor{
|
signDescriptors := []SignDescriptor{
|
||||||
{
|
{
|
||||||
PrivateTweak: []byte{
|
SingleTweak: []byte{
|
||||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
@ -66,7 +66,7 @@ func TestSignDescriptorSerialization(t *testing.T) {
|
||||||
|
|
||||||
// Test serializing a SignDescriptor with a nil-valued PrivateTweak
|
// Test serializing a SignDescriptor with a nil-valued PrivateTweak
|
||||||
{
|
{
|
||||||
PrivateTweak: nil,
|
SingleTweak: nil,
|
||||||
WitnessScript: []byte{
|
WitnessScript: []byte{
|
||||||
0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 0x85, 0x6c, 0xde,
|
0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 0x85, 0x6c, 0xde,
|
||||||
0x10, 0xa2, 0x91, 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2,
|
0x10, 0xa2, 0x91, 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2,
|
||||||
|
|
Loading…
Add table
Reference in a new issue