mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
202 lines
5.5 KiB
Go
202 lines
5.5 KiB
Go
package lnwire
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/btcsuite/btcd/btcec/v2"
|
|
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
|
|
"github.com/lightningnetwork/lnd/tlv"
|
|
)
|
|
|
|
const (
|
|
// PartialSigLen is the length of a musig2 partial signature.
|
|
PartialSigLen = 32
|
|
|
|
// PartialSigRecordType is the type of the tlv record for a musig2
|
|
// partial signature. This is an _even_ type, which means it's required
|
|
// if included.
|
|
PartialSigRecordType tlv.Type = 6
|
|
)
|
|
|
|
// PartialSig is the base partial sig type. This only encodes the 32-byte
|
|
// partial signature. This is used for the co-op close flow, as both sides have
|
|
// already exchanged nonces, so they can send just the partial signature.
|
|
type PartialSig struct {
|
|
// Sig is the 32-byte musig2 partial signature.
|
|
Sig btcec.ModNScalar
|
|
}
|
|
|
|
// NewPartialSig creates a new partial sig.
|
|
func NewPartialSig(sig btcec.ModNScalar) PartialSig {
|
|
return PartialSig{
|
|
Sig: sig,
|
|
}
|
|
}
|
|
|
|
// Record returns the tlv record for the partial sig.
|
|
func (p *PartialSig) Record() tlv.Record {
|
|
return tlv.MakeStaticRecord(
|
|
PartialSigRecordType, p, PartialSigLen,
|
|
partialSigTypeEncoder, partialSigTypeDecoder,
|
|
)
|
|
}
|
|
|
|
// partialSigTypeEncoder encodes a 32-byte musig2 partial signature as a TLV
|
|
// value.
|
|
func partialSigTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
|
|
if v, ok := val.(*PartialSig); ok {
|
|
sigBytes := v.Sig.Bytes()
|
|
|
|
return tlv.EBytes32(w, &sigBytes, buf)
|
|
}
|
|
|
|
return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSig")
|
|
}
|
|
|
|
// Encode writes the encoded version of this message to the passed io.Writer.
|
|
func (p *PartialSig) Encode(w io.Writer) error {
|
|
return partialSigTypeEncoder(w, p, nil)
|
|
}
|
|
|
|
// partialSigTypeDecoder decodes a 32-byte musig2 extended partial signature.
|
|
func partialSigTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
|
|
l uint64) error {
|
|
|
|
if v, ok := val.(*PartialSig); ok && l == PartialSigLen {
|
|
var sBytes [32]byte
|
|
err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var s btcec.ModNScalar
|
|
s.SetBytes(&sBytes)
|
|
|
|
*v = PartialSig{
|
|
Sig: s,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSig", l,
|
|
PartialSigLen)
|
|
}
|
|
|
|
// Decode reads the encoded version of this message from the passed io.Reader.
|
|
func (p *PartialSig) Decode(r io.Reader) error {
|
|
return partialSigTypeDecoder(r, p, nil, PartialSigLen)
|
|
}
|
|
|
|
const (
|
|
// PartialSigWithNonceLen is the length of a serialized
|
|
// PartialSigWithNonce. The sig is encoded as the 32 byte S value
|
|
// followed by the 66 nonce value.
|
|
PartialSigWithNonceLen = 98
|
|
|
|
// PartialSigWithNonceRecordType is the type of the tlv record for a
|
|
// musig2 partial signature with nonce. This is an _even_ type, which
|
|
// means it's required if included.
|
|
PartialSigWithNonceRecordType tlv.Type = 2
|
|
)
|
|
|
|
// PartialSigWithNonce is a partial signature with the nonce that was used to
|
|
// generate the signature. This is used for funding as well as the commitment
|
|
// transaction update dance. By sending the nonce only with the signature, we
|
|
// enable the sender to generate their nonce just before they create their
|
|
// signature. Signers can use this trait to mix in additional contextual data
|
|
// such as the commitment txn itself into their nonce generation function.
|
|
//
|
|
// The final signature is 98 bytes: 32 bytes for the S value, and 66 bytes for
|
|
// the public nonce (two compressed points).
|
|
type PartialSigWithNonce struct {
|
|
PartialSig
|
|
|
|
// Nonce is the 66-byte musig2 nonce.
|
|
Nonce Musig2Nonce
|
|
}
|
|
|
|
// NewPartialSigWithNonce creates a new partial sig with nonce.
|
|
func NewPartialSigWithNonce(nonce [musig2.PubNonceSize]byte,
|
|
sig btcec.ModNScalar) *PartialSigWithNonce {
|
|
|
|
return &PartialSigWithNonce{
|
|
Nonce: nonce,
|
|
PartialSig: NewPartialSig(sig),
|
|
}
|
|
}
|
|
|
|
// Record returns the tlv record for the partial sig with nonce.
|
|
func (p *PartialSigWithNonce) Record() tlv.Record {
|
|
return tlv.MakeStaticRecord(
|
|
PartialSigWithNonceRecordType, p, PartialSigWithNonceLen,
|
|
partialSigWithNonceTypeEncoder, partialSigWithNonceTypeDecoder,
|
|
)
|
|
}
|
|
|
|
// partialSigWithNonceTypeEncoder encodes 98-byte musig2 extended partial
|
|
// signature as: s {32} || nonce {66}.
|
|
func partialSigWithNonceTypeEncoder(w io.Writer, val interface{},
|
|
_ *[8]byte) error {
|
|
|
|
if v, ok := val.(*PartialSigWithNonce); ok {
|
|
sigBytes := v.Sig.Bytes()
|
|
if _, err := w.Write(sigBytes[:]); err != nil {
|
|
return err
|
|
}
|
|
if _, err := w.Write(v.Nonce[:]); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSigWithNonce")
|
|
}
|
|
|
|
// Encode writes the encoded version of this message to the passed io.Writer.
|
|
func (p *PartialSigWithNonce) Encode(w io.Writer) error {
|
|
return partialSigWithNonceTypeEncoder(w, p, nil)
|
|
}
|
|
|
|
// partialSigWithNonceTypeDecoder decodes a 98-byte musig2 extended partial
|
|
// signature.
|
|
func partialSigWithNonceTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
|
|
l uint64) error {
|
|
|
|
if v, ok := val.(*PartialSigWithNonce); ok &&
|
|
l == PartialSigWithNonceLen {
|
|
|
|
var sBytes [32]byte
|
|
err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var s btcec.ModNScalar
|
|
s.SetBytes(&sBytes)
|
|
|
|
var nonce [66]byte
|
|
if _, err := io.ReadFull(r, nonce[:]); err != nil {
|
|
return err
|
|
}
|
|
|
|
*v = PartialSigWithNonce{
|
|
PartialSig: NewPartialSig(s),
|
|
Nonce: nonce,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSigWithNonce", l,
|
|
PartialSigWithNonceLen)
|
|
}
|
|
|
|
// Decode reads the encoded version of this message from the passed io.Reader.
|
|
func (p *PartialSigWithNonce) Decode(r io.Reader) error {
|
|
return partialSigWithNonceTypeDecoder(
|
|
r, p, nil, PartialSigWithNonceLen,
|
|
)
|
|
}
|