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

lightningnetwork / lnd / 14193549836

01 Apr 2025 10:40AM UTC coverage: 69.046% (+0.007%) from 69.039%
14193549836

Pull #9665

github

web-flow
Merge e8825f209 into b01f4e514
Pull Request #9665: kvdb: bump etcd libs to v3.5.12

133439 of 193262 relevant lines covered (69.05%)

22119.45 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 {
528✔
40
        return PartialSig{
528✔
41
                Sig: sig,
528✔
42
        }
528✔
43
}
528✔
44

45
// Record returns the tlv record for the partial sig.
46
func (p *PartialSig) Record() tlv.Record {
219✔
47
        return tlv.MakeStaticRecord(
219✔
48
                (PartialSigType)(nil).TypeVal(), p, PartialSigLen,
219✔
49
                partialSigTypeEncoder, partialSigTypeDecoder,
219✔
50
        )
219✔
51
}
219✔
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 {
162✔
56
        if v, ok := val.(*PartialSig); ok {
324✔
57
                sigBytes := v.Sig.Bytes()
162✔
58

162✔
59
                return tlv.EBytes32(w, &sigBytes, buf)
162✔
60
        }
162✔
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 {
179✔
73

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

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

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

176✔
88
                return nil
176✔
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 {
51✔
102
        return tlv.SomeRecordT(tlv.NewRecordT[PartialSigType, PartialSig](sig))
51✔
103
}
51✔
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 {
164✔
150

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

157
// Record returns the tlv record for the partial sig with nonce.
158
func (p *PartialSigWithNonce) Record() tlv.Record {
4,887✔
159
        return tlv.MakeStaticRecord(
4,887✔
160
                (PartialSigWithNonceType)(nil).TypeVal(), p,
4,887✔
161
                PartialSigWithNonceLen, partialSigWithNonceTypeEncoder,
4,887✔
162
                partialSigWithNonceTypeDecoder,
4,887✔
163
        )
4,887✔
164
}
4,887✔
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 {
253✔
170

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

180
                return nil
253✔
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 {
198✔
195

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

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

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

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

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

189✔
218
                return nil
189✔
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,222✔
236

2,222✔
237
        if sig == nil {
4,198✔
238
                var none OptPartialSigWithNonceTLV
1,976✔
239
                return none
1,976✔
240
        }
1,976✔
241

242
        return tlv.SomeRecordT(
249✔
243
                tlv.NewRecordT[PartialSigWithNonceType, PartialSigWithNonce](
249✔
244
                        *sig,
249✔
245
                ),
249✔
246
        )
249✔
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

© 2026 Coveralls, Inc