partial_sig.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package lnwire
  2. import (
  3. "io"
  4. "github.com/btcsuite/btcd/btcec/v2"
  5. "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
  6. "github.com/lightningnetwork/lnd/tlv"
  7. )
  8. const (
  9. // PartialSigLen is the length of a musig2 partial signature.
  10. PartialSigLen = 32
  11. )
  12. type (
  13. // PartialSigType is the type of the tlv record for a musig2
  14. // partial signature. This is an _even_ type, which means it's required
  15. // if included.
  16. PartialSigType = tlv.TlvType6
  17. // PartialSigTLV is a tlv record for a musig2 partial signature.
  18. PartialSigTLV = tlv.RecordT[PartialSigType, PartialSig]
  19. // OptPartialSigTLV is a tlv record for a musig2 partial signature.
  20. // This is an optional record type.
  21. OptPartialSigTLV = tlv.OptionalRecordT[PartialSigType, PartialSig]
  22. )
  23. // PartialSig is the base partial sig type. This only encodes the 32-byte
  24. // partial signature. This is used for the co-op close flow, as both sides have
  25. // already exchanged nonces, so they can send just the partial signature.
  26. type PartialSig struct {
  27. // Sig is the 32-byte musig2 partial signature.
  28. Sig btcec.ModNScalar
  29. }
  30. // NewPartialSig creates a new partial sig.
  31. func NewPartialSig(sig btcec.ModNScalar) PartialSig {
  32. return PartialSig{
  33. Sig: sig,
  34. }
  35. }
  36. // Record returns the tlv record for the partial sig.
  37. func (p *PartialSig) Record() tlv.Record {
  38. return tlv.MakeStaticRecord(
  39. (PartialSigType)(nil).TypeVal(), p, PartialSigLen,
  40. partialSigTypeEncoder, partialSigTypeDecoder,
  41. )
  42. }
  43. // partialSigTypeEncoder encodes a 32-byte musig2 partial signature as a TLV
  44. // value.
  45. func partialSigTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
  46. if v, ok := val.(*PartialSig); ok {
  47. sigBytes := v.Sig.Bytes()
  48. return tlv.EBytes32(w, &sigBytes, buf)
  49. }
  50. return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSig")
  51. }
  52. // Encode writes the encoded version of this message to the passed io.Writer.
  53. func (p *PartialSig) Encode(w io.Writer) error {
  54. return partialSigTypeEncoder(w, p, nil)
  55. }
  56. // partialSigTypeDecoder decodes a 32-byte musig2 extended partial signature.
  57. func partialSigTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
  58. l uint64) error {
  59. if v, ok := val.(*PartialSig); ok && l == PartialSigLen {
  60. var sBytes [32]byte
  61. err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
  62. if err != nil {
  63. return err
  64. }
  65. var s btcec.ModNScalar
  66. s.SetBytes(&sBytes)
  67. *v = PartialSig{
  68. Sig: s,
  69. }
  70. return nil
  71. }
  72. return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSig", l,
  73. PartialSigLen)
  74. }
  75. // Decode reads the encoded version of this message from the passed io.Reader.
  76. func (p *PartialSig) Decode(r io.Reader) error {
  77. return partialSigTypeDecoder(r, p, nil, PartialSigLen)
  78. }
  79. // SomePartialSig is a helper function that returns an otional PartialSig.
  80. func SomePartialSig(sig PartialSig) OptPartialSigTLV {
  81. return tlv.SomeRecordT(tlv.NewRecordT[PartialSigType, PartialSig](sig))
  82. }
  83. const (
  84. // PartialSigWithNonceLen is the length of a serialized
  85. // PartialSigWithNonce. The sig is encoded as the 32 byte S value
  86. // followed by the 66 nonce value.
  87. PartialSigWithNonceLen = 98
  88. )
  89. type (
  90. // PartialSigWithNonceType is the type of the tlv record for a musig2
  91. // partial signature with nonce. This is an _even_ type, which means
  92. // it's required if included.
  93. PartialSigWithNonceType = tlv.TlvType2
  94. // PartialSigWithNonceTLV is a tlv record for a musig2 partial
  95. // signature.
  96. PartialSigWithNonceTLV = tlv.RecordT[
  97. PartialSigWithNonceType, PartialSigWithNonce,
  98. ]
  99. // OptPartialSigWithNonceTLV is a tlv record for a musig2 partial
  100. // signature. This is an optional record type.
  101. OptPartialSigWithNonceTLV = tlv.OptionalRecordT[
  102. PartialSigWithNonceType, PartialSigWithNonce,
  103. ]
  104. )
  105. // PartialSigWithNonce is a partial signature with the nonce that was used to
  106. // generate the signature. This is used for funding as well as the commitment
  107. // transaction update dance. By sending the nonce only with the signature, we
  108. // enable the sender to generate their nonce just before they create their
  109. // signature. Signers can use this trait to mix in additional contextual data
  110. // such as the commitment txn itself into their nonce generation function.
  111. //
  112. // The final signature is 98 bytes: 32 bytes for the S value, and 66 bytes for
  113. // the public nonce (two compressed points).
  114. type PartialSigWithNonce struct {
  115. PartialSig
  116. // Nonce is the 66-byte musig2 nonce.
  117. Nonce Musig2Nonce
  118. }
  119. // NewPartialSigWithNonce creates a new partial sig with nonce.
  120. func NewPartialSigWithNonce(nonce [musig2.PubNonceSize]byte,
  121. sig btcec.ModNScalar) *PartialSigWithNonce {
  122. return &PartialSigWithNonce{
  123. Nonce: nonce,
  124. PartialSig: NewPartialSig(sig),
  125. }
  126. }
  127. // Record returns the tlv record for the partial sig with nonce.
  128. func (p *PartialSigWithNonce) Record() tlv.Record {
  129. return tlv.MakeStaticRecord(
  130. (PartialSigWithNonceType)(nil).TypeVal(), p,
  131. PartialSigWithNonceLen, partialSigWithNonceTypeEncoder,
  132. partialSigWithNonceTypeDecoder,
  133. )
  134. }
  135. // partialSigWithNonceTypeEncoder encodes 98-byte musig2 extended partial
  136. // signature as: s {32} || nonce {66}.
  137. func partialSigWithNonceTypeEncoder(w io.Writer, val interface{},
  138. _ *[8]byte) error {
  139. if v, ok := val.(*PartialSigWithNonce); ok {
  140. sigBytes := v.Sig.Bytes()
  141. if _, err := w.Write(sigBytes[:]); err != nil {
  142. return err
  143. }
  144. if _, err := w.Write(v.Nonce[:]); err != nil {
  145. return err
  146. }
  147. return nil
  148. }
  149. return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSigWithNonce")
  150. }
  151. // Encode writes the encoded version of this message to the passed io.Writer.
  152. func (p *PartialSigWithNonce) Encode(w io.Writer) error {
  153. return partialSigWithNonceTypeEncoder(w, p, nil)
  154. }
  155. // partialSigWithNonceTypeDecoder decodes a 98-byte musig2 extended partial
  156. // signature.
  157. func partialSigWithNonceTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
  158. l uint64) error {
  159. if v, ok := val.(*PartialSigWithNonce); ok &&
  160. l == PartialSigWithNonceLen {
  161. var sBytes [32]byte
  162. err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
  163. if err != nil {
  164. return err
  165. }
  166. var s btcec.ModNScalar
  167. s.SetBytes(&sBytes)
  168. var nonce [66]byte
  169. if _, err := io.ReadFull(r, nonce[:]); err != nil {
  170. return err
  171. }
  172. *v = PartialSigWithNonce{
  173. PartialSig: NewPartialSig(s),
  174. Nonce: nonce,
  175. }
  176. return nil
  177. }
  178. return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSigWithNonce", l,
  179. PartialSigWithNonceLen)
  180. }
  181. // Decode reads the encoded version of this message from the passed io.Reader.
  182. func (p *PartialSigWithNonce) Decode(r io.Reader) error {
  183. return partialSigWithNonceTypeDecoder(
  184. r, p, nil, PartialSigWithNonceLen,
  185. )
  186. }
  187. // MaybePartialSigWithNonce is a helper function that returns an optional
  188. // PartialSigWithNonceTLV.
  189. func MaybePartialSigWithNonce(sig *PartialSigWithNonce,
  190. ) OptPartialSigWithNonceTLV {
  191. if sig == nil {
  192. var none OptPartialSigWithNonceTLV
  193. return none
  194. }
  195. return tlv.SomeRecordT(
  196. tlv.NewRecordT[PartialSigWithNonceType, PartialSigWithNonce](
  197. *sig,
  198. ),
  199. )
  200. }