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

lightningnetwork / lnd / 13586005509

28 Feb 2025 10:14AM UTC coverage: 68.629% (+9.9%) from 58.77%
13586005509

Pull #9521

github

web-flow
Merge 37d3a70a5 into 8532955b3
Pull Request #9521: unit: remove GOACC, use Go 1.20 native coverage functionality

129950 of 189351 relevant lines covered (68.63%)

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

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

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

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

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

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

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

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

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

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

180
                return nil
246✔
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 {
191✔
195

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

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

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

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

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

182✔
218
                return nil
182✔
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,100✔
236

2,100✔
237
        if sig == nil {
4,117✔
238
                var none OptPartialSigWithNonceTLV
2,017✔
239
                return none
2,017✔
240
        }
2,017✔
241

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