• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 15951470896

29 Jun 2025 04:23AM UTC coverage: 67.594% (-0.01%) from 67.606%
15951470896

Pull #9751

github

web-flow
Merge 599d9b051 into 6290edf14
Pull Request #9751: multi: update Go to 1.23.10 and update some packages

135088 of 199851 relevant lines covered (67.59%)

21909.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.78
/lnwire/partial_sig.go
1
package lnwire
2

3
import (
4
        "io"
5

6
        "github.com/btcsuite/btcd/btcec/v2"
7
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
8
        "github.com/lightningnetwork/lnd/tlv"
9
)
10

11
const (
12
        // PartialSigLen is the length of a musig2 partial signature.
13
        PartialSigLen = 32
14
)
15

16
type (
17
        // PartialSigType is the type of the tlv record for a musig2
18
        // partial signature. This is an _even_ type, which means it's required
19
        // if included.
20
        PartialSigType = tlv.TlvType6
21

22
        // PartialSigTLV is a tlv record for a musig2 partial signature.
23
        PartialSigTLV = tlv.RecordT[PartialSigType, PartialSig]
24

25
        // OptPartialSigTLV is a tlv record for a musig2 partial signature.
26
        // This is an optional record type.
27
        OptPartialSigTLV = tlv.OptionalRecordT[PartialSigType, PartialSig]
28
)
29

30
// PartialSig is the base partial sig type. This only encodes the 32-byte
31
// partial signature. This is used for the co-op close flow, as both sides have
32
// already exchanged nonces, so they can send just the partial signature.
33
type PartialSig struct {
34
        // Sig is the 32-byte musig2 partial signature.
35
        Sig btcec.ModNScalar
36
}
37

38
// NewPartialSig creates a new partial sig.
39
func NewPartialSig(sig btcec.ModNScalar) PartialSig {
505✔
40
        return PartialSig{
505✔
41
                Sig: sig,
505✔
42
        }
505✔
43
}
505✔
44

45
// Record returns the tlv record for the partial sig.
46
func (p *PartialSig) Record() tlv.Record {
230✔
47
        return tlv.MakeStaticRecord(
230✔
48
                (PartialSigType)(nil).TypeVal(), p, PartialSigLen,
230✔
49
                partialSigTypeEncoder, partialSigTypeDecoder,
230✔
50
        )
230✔
51
}
230✔
52

53
// partialSigTypeEncoder encodes a 32-byte musig2 partial signature as a TLV
54
// value.
55
func partialSigTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
173✔
56
        if v, ok := val.(*PartialSig); ok {
346✔
57
                sigBytes := v.Sig.Bytes()
173✔
58

173✔
59
                return tlv.EBytes32(w, &sigBytes, buf)
173✔
60
        }
173✔
61

62
        return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSig")
×
63
}
64

65
// Encode writes the encoded version of this message to the passed io.Writer.
66
func (p *PartialSig) Encode(w io.Writer) error {
111✔
67
        return partialSigTypeEncoder(w, p, nil)
111✔
68
}
111✔
69

70
// partialSigTypeDecoder decodes a 32-byte musig2 extended partial signature.
71
func partialSigTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
72
        l uint64) error {
190✔
73

190✔
74
        if v, ok := val.(*PartialSig); ok && l == PartialSigLen {
379✔
75
                var sBytes [32]byte
189✔
76
                err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
189✔
77
                if err != nil {
191✔
78
                        return err
2✔
79
                }
2✔
80

81
                var s btcec.ModNScalar
187✔
82
                s.SetBytes(&sBytes)
187✔
83

187✔
84
                *v = PartialSig{
187✔
85
                        Sig: s,
187✔
86
                }
187✔
87

187✔
88
                return nil
187✔
89
        }
90

91
        return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSig", l,
1✔
92
                PartialSigLen)
1✔
93
}
94

95
// Decode reads the encoded version of this message from the passed io.Reader.
96
func (p *PartialSig) Decode(r io.Reader) error {
123✔
97
        return partialSigTypeDecoder(r, p, nil, PartialSigLen)
123✔
98
}
123✔
99

100
// SomePartialSig is a helper function that returns an otional PartialSig.
101
func SomePartialSig(sig PartialSig) OptPartialSigTLV {
62✔
102
        return tlv.SomeRecordT(tlv.NewRecordT[PartialSigType, PartialSig](sig))
62✔
103
}
62✔
104

105
const (
106
        // PartialSigWithNonceLen is the length of a serialized
107
        // PartialSigWithNonce. The sig is encoded as the 32 byte S value
108
        // followed by the 66 nonce value.
109
        PartialSigWithNonceLen = 98
110
)
111

112
type (
113
        // PartialSigWithNonceType is the type of the tlv record for a musig2
114
        // partial signature with nonce. This is an _even_ type, which means
115
        // it's required if included.
116
        PartialSigWithNonceType = tlv.TlvType2
117

118
        // PartialSigWithNonceTLV is a tlv record for a musig2 partial
119
        // signature.
120
        PartialSigWithNonceTLV = tlv.RecordT[
121
                PartialSigWithNonceType, PartialSigWithNonce,
122
        ]
123

124
        // OptPartialSigWithNonceTLV is a tlv record for a musig2 partial
125
        // signature.  This is an optional record type.
126
        OptPartialSigWithNonceTLV = tlv.OptionalRecordT[
127
                PartialSigWithNonceType, PartialSigWithNonce,
128
        ]
129
)
130

131
// PartialSigWithNonce is a partial signature with the nonce that was used to
132
// generate the signature. This is used for funding as well as the commitment
133
// transaction update dance. By sending the nonce only with the signature, we
134
// enable the sender to generate their nonce just before they create their
135
// signature. Signers can use this trait to mix in additional contextual data
136
// such as the commitment txn itself into their nonce generation function.
137
//
138
// The final signature is 98 bytes: 32 bytes for the S value, and 66 bytes for
139
// the public nonce (two compressed points).
140
type PartialSigWithNonce struct {
141
        PartialSig
142

143
        // Nonce is the 66-byte musig2 nonce.
144
        Nonce Musig2Nonce
145
}
146

147
// NewPartialSigWithNonce creates a new partial sig with nonce.
148
func NewPartialSigWithNonce(nonce [musig2.PubNonceSize]byte,
149
        sig btcec.ModNScalar) *PartialSigWithNonce {
147✔
150

147✔
151
        return &PartialSigWithNonce{
147✔
152
                Nonce:      nonce,
147✔
153
                PartialSig: NewPartialSig(sig),
147✔
154
        }
147✔
155
}
147✔
156

157
// Record returns the tlv record for the partial sig with nonce.
158
func (p *PartialSigWithNonce) Record() tlv.Record {
4,876✔
159
        return tlv.MakeStaticRecord(
4,876✔
160
                (PartialSigWithNonceType)(nil).TypeVal(), p,
4,876✔
161
                PartialSigWithNonceLen, partialSigWithNonceTypeEncoder,
4,876✔
162
                partialSigWithNonceTypeDecoder,
4,876✔
163
        )
4,876✔
164
}
4,876✔
165

166
// partialSigWithNonceTypeEncoder encodes 98-byte musig2 extended partial
167
// signature as: s {32} || nonce {66}.
168
func partialSigWithNonceTypeEncoder(w io.Writer, val interface{},
169
        _ *[8]byte) error {
236✔
170

236✔
171
        if v, ok := val.(*PartialSigWithNonce); ok {
472✔
172
                sigBytes := v.Sig.Bytes()
236✔
173
                if _, err := w.Write(sigBytes[:]); err != nil {
236✔
174
                        return err
×
175
                }
×
176
                if _, err := w.Write(v.Nonce[:]); err != nil {
236✔
177
                        return err
×
178
                }
×
179

180
                return nil
236✔
181
        }
182

183
        return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSigWithNonce")
×
184
}
185

186
// Encode writes the encoded version of this message to the passed io.Writer.
187
func (p *PartialSigWithNonce) Encode(w io.Writer) error {
83✔
188
        return partialSigWithNonceTypeEncoder(w, p, nil)
83✔
189
}
83✔
190

191
// partialSigWithNonceTypeDecoder decodes a 98-byte musig2 extended partial
192
// signature.
193
func partialSigWithNonceTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
194
        l uint64) error {
181✔
195

181✔
196
        if v, ok := val.(*PartialSigWithNonce); ok &&
181✔
197
                l == PartialSigWithNonceLen {
359✔
198

178✔
199
                var sBytes [32]byte
178✔
200
                err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
178✔
201
                if err != nil {
181✔
202
                        return err
3✔
203
                }
3✔
204

205
                var s btcec.ModNScalar
175✔
206
                s.SetBytes(&sBytes)
175✔
207

175✔
208
                var nonce [66]byte
175✔
209
                if _, err := io.ReadFull(r, nonce[:]); err != nil {
178✔
210
                        return err
3✔
211
                }
3✔
212

213
                *v = PartialSigWithNonce{
172✔
214
                        PartialSig: NewPartialSig(s),
172✔
215
                        Nonce:      nonce,
172✔
216
                }
172✔
217

172✔
218
                return nil
172✔
219
        }
220

221
        return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSigWithNonce", l,
3✔
222
                PartialSigWithNonceLen)
3✔
223
}
224

225
// Decode reads the encoded version of this message from the passed io.Reader.
226
func (p *PartialSigWithNonce) Decode(r io.Reader) error {
11✔
227
        return partialSigWithNonceTypeDecoder(
11✔
228
                r, p, nil, PartialSigWithNonceLen,
11✔
229
        )
11✔
230
}
11✔
231

232
// MaybePartialSigWithNonce is a helper function that returns an optional
233
// PartialSigWithNonceTLV.
234
func MaybePartialSigWithNonce(sig *PartialSigWithNonce,
235
) OptPartialSigWithNonceTLV {
2,209✔
236

2,209✔
237
        if sig == nil {
4,189✔
238
                var none OptPartialSigWithNonceTLV
1,980✔
239
                return none
1,980✔
240
        }
1,980✔
241

242
        return tlv.SomeRecordT(
232✔
243
                tlv.NewRecordT[PartialSigWithNonceType, PartialSigWithNonce](
232✔
244
                        *sig,
232✔
245
                ),
232✔
246
        )
232✔
247
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc