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

lightningnetwork / lnd / 11170835610

03 Oct 2024 10:41PM UTC coverage: 49.188% (-9.6%) from 58.738%
11170835610

push

github

web-flow
Merge pull request #9154 from ziggie1984/master

multi: bump btcd version.

3 of 6 new or added lines in 6 files covered. (50.0%)

26110 existing lines in 428 files now uncovered.

97359 of 197934 relevant lines covered (49.19%)

1.04 hits per line

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

75.92
/internal/musig2v040/nonces.go
1
// Copyright 2013-2022 The btcsuite developers
2

3
package musig2v040
4

5
import (
6
        "bytes"
7
        "crypto/rand"
8
        "encoding/binary"
9
        "io"
10

11
        "github.com/btcsuite/btcd/btcec/v2"
12
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
13
        "github.com/btcsuite/btcd/chaincfg/chainhash"
14
)
15

16
const (
17
        // PubNonceSize is the size of the public nonces. Each public nonce is
18
        // serialized the full compressed encoding, which uses 32 bytes for each
19
        // nonce.
20
        PubNonceSize = 66
21

22
        // SecNonceSize is the size of the secret nonces for musig2. The secret
23
        // nonces are the corresponding private keys to the public nonce points.
24
        SecNonceSize = 64
25
)
26

27
var (
28
        // NonceAuxTag is the tag used to optionally mix in the secret key with
29
        // the set of aux randomness.
30
        NonceAuxTag = []byte("MuSig/aux")
31

32
        // NonceGenTag is used to generate the value (from a set of required an
33
        // optional field) that will be used as the part of the secret nonce.
34
        NonceGenTag = []byte("MuSig/nonce")
35

36
        byteOrder = binary.BigEndian
37
)
38

39
// zeroSecNonce is a secret nonce that's all zeroes. This is used to check that
40
// we're not attempting to re-use a nonce, and also protect callers from it.
41
var zeroSecNonce [SecNonceSize]byte
42

43
// Nonces holds the public and secret nonces required for musig2.
44
//
45
// TODO(roasbeef): methods on this to help w/ parsing, etc?
46
type Nonces struct {
47
        // PubNonce holds the two 33-byte compressed encoded points that serve
48
        // as the public set of nonces.
49
        PubNonce [PubNonceSize]byte
50

51
        // SecNonce holds the two 32-byte scalar values that are the private
52
        // keys to the two public nonces.
53
        SecNonce [SecNonceSize]byte
54
}
55

56
// secNonceToPubNonce takes our two secrete nonces, and produces their two
57
// corresponding EC points, serialized in compressed format.
58
func secNonceToPubNonce(secNonce [SecNonceSize]byte) [PubNonceSize]byte {
2✔
59
        var k1Mod, k2Mod btcec.ModNScalar
2✔
60
        k1Mod.SetByteSlice(secNonce[:btcec.PrivKeyBytesLen])
2✔
61
        k2Mod.SetByteSlice(secNonce[btcec.PrivKeyBytesLen:])
2✔
62

2✔
63
        var r1, r2 btcec.JacobianPoint
2✔
64
        btcec.ScalarBaseMultNonConst(&k1Mod, &r1)
2✔
65
        btcec.ScalarBaseMultNonConst(&k2Mod, &r2)
2✔
66

2✔
67
        // Next, we'll convert the key in jacobian format to a normal public
2✔
68
        // key expressed in affine coordinates.
2✔
69
        r1.ToAffine()
2✔
70
        r2.ToAffine()
2✔
71
        r1Pub := btcec.NewPublicKey(&r1.X, &r1.Y)
2✔
72
        r2Pub := btcec.NewPublicKey(&r2.X, &r2.Y)
2✔
73

2✔
74
        var pubNonce [PubNonceSize]byte
2✔
75

2✔
76
        // The public nonces are serialized as: R1 || R2, where both keys are
2✔
77
        // serialized in compressed format.
2✔
78
        copy(pubNonce[:], r1Pub.SerializeCompressed())
2✔
79
        copy(
2✔
80
                pubNonce[btcec.PubKeyBytesLenCompressed:],
2✔
81
                r2Pub.SerializeCompressed(),
2✔
82
        )
2✔
83

2✔
84
        return pubNonce
2✔
85
}
2✔
86

87
// NonceGenOption is a function option that allows callers to modify how nonce
88
// generation happens.
89
type NonceGenOption func(*nonceGenOpts)
90

91
// nonceGenOpts is the set of options that control how nonce generation
92
// happens.
93
type nonceGenOpts struct {
94
        // randReader is what we'll use to generate a set of random bytes. If
95
        // unspecified, then the normal crypto/rand rand.Read method will be
96
        // used in place.
97
        randReader io.Reader
98

99
        // secretKey is an optional argument that's used to further augment the
100
        // generated nonce by xor'ing it with this secret key.
101
        secretKey []byte
102

103
        // combinedKey is an optional argument that if specified, will be
104
        // combined along with the nonce generation.
105
        combinedKey []byte
106

107
        // msg is an optional argument that will be mixed into the nonce
108
        // derivation algorithm.
109
        msg []byte
110

111
        // auxInput is an optional argument that will be mixed into the nonce
112
        // derivation algorithm.
113
        auxInput []byte
114
}
115

116
// cryptoRandAdapter is an adapter struct that allows us to pass in the package
117
// level Read function from crypto/rand into a context that accepts an
118
// io.Reader.
119
type cryptoRandAdapter struct {
120
}
121

122
// Read implements the io.Reader interface for the crypto/rand package.  By
123
// default, we always use the crypto/rand reader, but the caller is able to
124
// specify their own generation, which can be useful for deterministic tests.
125
func (c *cryptoRandAdapter) Read(p []byte) (n int, err error) {
2✔
126
        return rand.Read(p)
2✔
127
}
2✔
128

129
// defaultNonceGenOpts returns the default set of nonce generation options.
130
func defaultNonceGenOpts() *nonceGenOpts {
2✔
131
        return &nonceGenOpts{
2✔
132
                randReader: &cryptoRandAdapter{},
2✔
133
        }
2✔
134
}
2✔
135

136
// WithCustomRand allows a caller to use a custom random number generator in
137
// place for crypto/rand. This should only really be used to generate
138
// determinstic tests.
139
func WithCustomRand(r io.Reader) NonceGenOption {
×
140
        return func(o *nonceGenOpts) {
×
141
                o.randReader = r
×
142
        }
×
143
}
144

145
// WithNonceSecretKeyAux allows a caller to optionally specify a secret key
146
// that should be used to augment the randomness used to generate the nonces.
147
func WithNonceSecretKeyAux(secKey *btcec.PrivateKey) NonceGenOption {
2✔
148
        return func(o *nonceGenOpts) {
4✔
149
                o.secretKey = secKey.Serialize()
2✔
150
        }
2✔
151
}
152

153
// WithNonceCombinedKeyAux allows a caller to optionally specify the combined
154
// key used in this signing session to further augment the randomness used to
155
// generate nonces.
156
func WithNonceCombinedKeyAux(combinedKey *btcec.PublicKey) NonceGenOption {
2✔
157
        return func(o *nonceGenOpts) {
4✔
158
                o.combinedKey = schnorr.SerializePubKey(combinedKey)
2✔
159
        }
2✔
160
}
161

162
// WithNonceMessageAux allows a caller to optionally specify a message to be
163
// mixed into the randomness generated to create the nonce.
164
func WithNonceMessageAux(msg [32]byte) NonceGenOption {
×
165
        return func(o *nonceGenOpts) {
×
166
                o.msg = msg[:]
×
167
        }
×
168
}
169

170
// WithNonceAuxInput is a set of auxiliary randomness, similar to BIP 340 that
171
// can be used to further augment the nonce generation process.
172
func WithNonceAuxInput(aux []byte) NonceGenOption {
×
173
        return func(o *nonceGenOpts) {
×
174
                o.auxInput = aux
×
175
        }
×
176
}
177

178
// withCustomOptions allows a caller to pass a complete set of custom
179
// nonceGenOpts, without needing to create custom and checked structs such as
180
// *btcec.PrivateKey. This is mainly used to match the testcases provided by
181
// the MuSig2 BIP.
UNCOV
182
func withCustomOptions(customOpts nonceGenOpts) NonceGenOption {
×
UNCOV
183
        return func(o *nonceGenOpts) {
×
UNCOV
184
                o.randReader = customOpts.randReader
×
UNCOV
185
                o.secretKey = customOpts.secretKey
×
UNCOV
186
                o.combinedKey = customOpts.combinedKey
×
UNCOV
187
                o.msg = customOpts.msg
×
UNCOV
188
                o.auxInput = customOpts.auxInput
×
UNCOV
189
        }
×
190
}
191

192
// lengthWriter is a function closure that allows a caller to control how the
193
// length prefix of a byte slice is written.
194
type lengthWriter func(w io.Writer, b []byte) error
195

196
// uint8Writer is an implementation of lengthWriter that writes the length of
197
// the byte slice using 1 byte.
198
func uint8Writer(w io.Writer, b []byte) error {
2✔
199
        return binary.Write(w, byteOrder, uint8(len(b)))
2✔
200
}
2✔
201

202
// uint32Writer is an implementation of lengthWriter that writes the length of
203
// the byte slice using 4 bytes.
204
func uint32Writer(w io.Writer, b []byte) error {
2✔
205
        return binary.Write(w, byteOrder, uint32(len(b)))
2✔
206
}
2✔
207

208
// writeBytesPrefix is used to write out: len(b) || b, to the passed io.Writer.
209
// The lengthWriter function closure is used to allow the caller to specify the
210
// precise byte packing of the length.
211
func writeBytesPrefix(w io.Writer, b []byte, lenWriter lengthWriter) error {
2✔
212
        // Write out the length of the byte first, followed by the set of bytes
2✔
213
        // itself.
2✔
214
        if err := lenWriter(w, b); err != nil {
2✔
215
                return err
×
216
        }
×
217

218
        if _, err := w.Write(b); err != nil {
2✔
219
                return err
×
220
        }
×
221

222
        return nil
2✔
223
}
224

225
// genNonceAuxBytes writes out the full byte string used to derive a secret
226
// nonce based on some initial randomness as well as the series of optional
227
// fields. The byte string used for derivation is:
228
//   - tagged_hash("MuSig/nonce", rand || len(aggpk) || aggpk || len(m)
229
//     || m || len(in) || in || i).
230
//
231
// where i is the ith secret nonce being generated.
232
func genNonceAuxBytes(rand []byte, i int,
233
        opts *nonceGenOpts) (*chainhash.Hash, error) {
2✔
234

2✔
235
        var w bytes.Buffer
2✔
236

2✔
237
        // First, write out the randomness generated in the prior step.
2✔
238
        if _, err := w.Write(rand); err != nil {
2✔
239
                return nil, err
×
240
        }
×
241

242
        // Next, we'll write out: len(aggpk) || aggpk.
243
        err := writeBytesPrefix(&w, opts.combinedKey, uint8Writer)
2✔
244
        if err != nil {
2✔
245
                return nil, err
×
246
        }
×
247

248
        // Next, we'll write out the length prefixed message.
249
        err = writeBytesPrefix(&w, opts.msg, uint8Writer)
2✔
250
        if err != nil {
2✔
251
                return nil, err
×
252
        }
×
253

254
        // Finally we'll write out the auxiliary input.
255
        err = writeBytesPrefix(&w, opts.auxInput, uint32Writer)
2✔
256
        if err != nil {
2✔
257
                return nil, err
×
258
        }
×
259

260
        // Next we'll write out the interaction/index number which will
261
        // uniquely generate two nonces given the rest of the possibly static
262
        // parameters.
263
        if err := binary.Write(&w, byteOrder, uint8(i)); err != nil {
2✔
264
                return nil, err
×
265
        }
×
266

267
        // With the message buffer complete, we'll now derive the tagged hash
268
        // using our set of params.
269
        return chainhash.TaggedHash(NonceGenTag, w.Bytes()), nil
2✔
270
}
271

272
// GenNonces generates the secret nonces, as well as the public nonces which
273
// correspond to an EC point generated using the secret nonce as a private key.
274
func GenNonces(options ...NonceGenOption) (*Nonces, error) {
2✔
275
        opts := defaultNonceGenOpts()
2✔
276
        for _, opt := range options {
4✔
277
                opt(opts)
2✔
278
        }
2✔
279

280
        // First, we'll start out by generating 32 random bytes drawn from our
281
        // CSPRNG.
282
        var randBytes [32]byte
2✔
283
        if _, err := opts.randReader.Read(randBytes[:]); err != nil {
2✔
284
                return nil, err
×
285
        }
×
286

287
        // If the options contain a secret key, we XOR it with with the tagged
288
        // random bytes.
289
        if len(opts.secretKey) == 32 {
4✔
290
                taggedHash := chainhash.TaggedHash(NonceAuxTag, randBytes[:])
2✔
291

2✔
292
                for i := 0; i < chainhash.HashSize; i++ {
4✔
293
                        randBytes[i] = opts.secretKey[i] ^ taggedHash[i]
2✔
294
                }
2✔
295
        }
296

297
        // Using our randomness and the set of optional params, generate our
298
        // two secret nonces: k1 and k2.
299
        k1, err := genNonceAuxBytes(randBytes[:], 0, opts)
2✔
300
        if err != nil {
2✔
301
                return nil, err
×
302
        }
×
303
        k2, err := genNonceAuxBytes(randBytes[:], 1, opts)
2✔
304
        if err != nil {
2✔
305
                return nil, err
×
306
        }
×
307

308
        var k1Mod, k2Mod btcec.ModNScalar
2✔
309
        k1Mod.SetBytes((*[32]byte)(k1))
2✔
310
        k2Mod.SetBytes((*[32]byte)(k2))
2✔
311

2✔
312
        // The secret nonces are serialized as the concatenation of the two 32
2✔
313
        // byte secret nonce values.
2✔
314
        var nonces Nonces
2✔
315
        k1Mod.PutBytesUnchecked(nonces.SecNonce[:])
2✔
316
        k2Mod.PutBytesUnchecked(nonces.SecNonce[btcec.PrivKeyBytesLen:])
2✔
317

2✔
318
        // Next, we'll generate R_1 = k_1*G and R_2 = k_2*G. Along the way we
2✔
319
        // need to map our nonce values into mod n scalars so we can work with
2✔
320
        // the btcec API.
2✔
321
        nonces.PubNonce = secNonceToPubNonce(nonces.SecNonce)
2✔
322

2✔
323
        return &nonces, nil
2✔
324
}
325

326
// AggregateNonces aggregates the set of a pair of public nonces for each party
327
// into a single aggregated nonces to be used for multi-signing.
328
func AggregateNonces(pubNonces [][PubNonceSize]byte) ([PubNonceSize]byte, error) {
2✔
329
        // combineNonces is a helper function that aggregates (adds) up a
2✔
330
        // series of nonces encoded in compressed format. It uses a slicing
2✔
331
        // function to extra 33 bytes at a time from the packed 2x public
2✔
332
        // nonces.
2✔
333
        type nonceSlicer func([PubNonceSize]byte) []byte
2✔
334
        combineNonces := func(slicer nonceSlicer) (btcec.JacobianPoint, error) {
4✔
335
                // Convert the set of nonces into jacobian coordinates we can
2✔
336
                // use to accumulate them all into each other.
2✔
337
                pubNonceJs := make([]*btcec.JacobianPoint, len(pubNonces))
2✔
338
                for i, pubNonceBytes := range pubNonces {
4✔
339
                        // Using the slicer, extract just the bytes we need to
2✔
340
                        // decode.
2✔
341
                        var nonceJ btcec.JacobianPoint
2✔
342

2✔
343
                        nonceJ, err := btcec.ParseJacobian(slicer(pubNonceBytes))
2✔
344
                        if err != nil {
2✔
UNCOV
345
                                return btcec.JacobianPoint{}, err
×
UNCOV
346
                        }
×
347

348
                        pubNonceJs[i] = &nonceJ
2✔
349
                }
350

351
                // Now that we have the set of complete nonces, we'll aggregate
352
                // them: R = R_i + R_i+1 + ... + R_i+n.
353
                var aggregateNonce btcec.JacobianPoint
2✔
354
                for _, pubNonceJ := range pubNonceJs {
4✔
355
                        btcec.AddNonConst(
2✔
356
                                &aggregateNonce, pubNonceJ, &aggregateNonce,
2✔
357
                        )
2✔
358
                }
2✔
359

360
                aggregateNonce.ToAffine()
2✔
361
                return aggregateNonce, nil
2✔
362
        }
363

364
        // The final nonce public nonce is actually two nonces, one that
365
        // aggregate the first nonce of all the parties, and the other that
366
        // aggregates the second nonce of all the parties.
367
        var finalNonce [PubNonceSize]byte
2✔
368
        combinedNonce1, err := combineNonces(func(n [PubNonceSize]byte) []byte {
4✔
369
                return n[:btcec.PubKeyBytesLenCompressed]
2✔
370
        })
2✔
371
        if err != nil {
2✔
UNCOV
372
                return finalNonce, err
×
UNCOV
373
        }
×
374

375
        combinedNonce2, err := combineNonces(func(n [PubNonceSize]byte) []byte {
4✔
376
                return n[btcec.PubKeyBytesLenCompressed:]
2✔
377
        })
2✔
378
        if err != nil {
2✔
UNCOV
379
                return finalNonce, err
×
UNCOV
380
        }
×
381

382
        copy(finalNonce[:], btcec.JacobianToByteSlice(combinedNonce1))
2✔
383
        copy(
2✔
384
                finalNonce[btcec.PubKeyBytesLenCompressed:],
2✔
385
                btcec.JacobianToByteSlice(combinedNonce2),
2✔
386
        )
2✔
387

2✔
388
        return finalNonce, nil
2✔
389
}
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