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

lightningnetwork / lnd / 13725358077

07 Mar 2025 04:51PM UTC coverage: 58.224% (-10.4%) from 68.615%
13725358077

Pull #9458

github

web-flow
Merge bf4c6625f into ab2dc09eb
Pull Request #9458: multi+server.go: add initial permissions for some peers

346 of 549 new or added lines in 10 files covered. (63.02%)

27466 existing lines in 443 files now uncovered.

94609 of 162492 relevant lines covered (58.22%)

1.81 hits per line

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

76.51
/input/script_utils.go
1
package input
2

3
import (
4
        "bytes"
5
        "crypto/sha256"
6
        "encoding/hex"
7
        "fmt"
8

9
        "github.com/btcsuite/btcd/btcec/v2"
10
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
11
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
12
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
13
        "github.com/btcsuite/btcd/btcutil"
14
        "github.com/btcsuite/btcd/chaincfg/chainhash"
15
        "github.com/btcsuite/btcd/txscript"
16
        "github.com/btcsuite/btcd/wire"
17
        "github.com/lightningnetwork/lnd/fn/v2"
18
        "github.com/lightningnetwork/lnd/lntypes"
19
        "github.com/lightningnetwork/lnd/lnutils"
20
        "golang.org/x/crypto/ripemd160"
21
)
22

23
var (
24
        // TODO(roasbeef): remove these and use the one's defined in txscript
25
        // within testnet-L.
26

27
        // SequenceLockTimeSeconds is the 22nd bit which indicates the lock
28
        // time is in seconds.
29
        SequenceLockTimeSeconds = uint32(1 << 22)
30
)
31

32
// MustParsePubKey parses a hex encoded public key string into a public key and
33
// panic if parsing fails.
34
func MustParsePubKey(pubStr string) btcec.PublicKey {
3✔
35
        pubBytes, err := hex.DecodeString(pubStr)
3✔
36
        if err != nil {
3✔
37
                panic(err)
×
38
        }
39

40
        pub, err := btcec.ParsePubKey(pubBytes)
3✔
41
        if err != nil {
3✔
42
                panic(err)
×
43
        }
44

45
        return *pub
3✔
46
}
47

48
// TaprootNUMSHex is the hex encoded version of the taproot NUMs key.
49
const TaprootNUMSHex = "02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb" +
50
        "6bf4bc130a279"
51

52
var (
53
        // TaprootNUMSKey is a NUMS key (nothing up my sleeves number) that has
54
        // no known private key. This was generated using the following script:
55
        // https://github.com/lightninglabs/lightning-node-connect/tree/
56
        // master/mailbox/numsgen, with the seed phrase "Lightning Simple
57
        // Taproot".
58
        TaprootNUMSKey = MustParsePubKey(TaprootNUMSHex)
59
)
60

61
// Signature is an interface for objects that can populate signatures during
62
// witness construction.
63
type Signature interface {
64
        // Serialize returns a DER-encoded ECDSA signature.
65
        Serialize() []byte
66

67
        // Verify return true if the ECDSA signature is valid for the passed
68
        // message digest under the provided public key.
69
        Verify([]byte, *btcec.PublicKey) bool
70
}
71

72
// ParseSignature parses a raw signature into an input.Signature instance. This
73
// routine supports parsing normal ECDSA DER encoded signatures, as well as
74
// schnorr signatures.
75
func ParseSignature(rawSig []byte) (Signature, error) {
3✔
76
        if len(rawSig) == schnorr.SignatureSize {
6✔
77
                return schnorr.ParseSignature(rawSig)
3✔
78
        }
3✔
79

80
        return ecdsa.ParseDERSignature(rawSig)
3✔
81
}
82

83
// WitnessScriptHash generates a pay-to-witness-script-hash public key script
84
// paying to a version 0 witness program paying to the passed redeem script.
85
func WitnessScriptHash(witnessScript []byte) ([]byte, error) {
3✔
86
        bldr := txscript.NewScriptBuilder(
3✔
87
                txscript.WithScriptAllocSize(P2WSHSize),
3✔
88
        )
3✔
89

3✔
90
        bldr.AddOp(txscript.OP_0)
3✔
91
        scriptHash := sha256.Sum256(witnessScript)
3✔
92
        bldr.AddData(scriptHash[:])
3✔
93
        return bldr.Script()
3✔
94
}
3✔
95

96
// WitnessPubKeyHash generates a pay-to-witness-pubkey-hash public key script
97
// paying to a version 0 witness program containing the passed serialized
98
// public key.
99
func WitnessPubKeyHash(pubkey []byte) ([]byte, error) {
3✔
100
        bldr := txscript.NewScriptBuilder(
3✔
101
                txscript.WithScriptAllocSize(P2WPKHSize),
3✔
102
        )
3✔
103

3✔
104
        bldr.AddOp(txscript.OP_0)
3✔
105
        pkhash := btcutil.Hash160(pubkey)
3✔
106
        bldr.AddData(pkhash)
3✔
107
        return bldr.Script()
3✔
108
}
3✔
109

110
// GenerateP2SH generates a pay-to-script-hash public key script paying to the
111
// passed redeem script.
112
func GenerateP2SH(script []byte) ([]byte, error) {
3✔
113
        bldr := txscript.NewScriptBuilder(
3✔
114
                txscript.WithScriptAllocSize(NestedP2WPKHSize),
3✔
115
        )
3✔
116

3✔
117
        bldr.AddOp(txscript.OP_HASH160)
3✔
118
        scripthash := btcutil.Hash160(script)
3✔
119
        bldr.AddData(scripthash)
3✔
120
        bldr.AddOp(txscript.OP_EQUAL)
3✔
121
        return bldr.Script()
3✔
122
}
3✔
123

124
// GenerateP2PKH generates a pay-to-public-key-hash public key script paying to
125
// the passed serialized public key.
126
func GenerateP2PKH(pubkey []byte) ([]byte, error) {
3✔
127
        bldr := txscript.NewScriptBuilder(
3✔
128
                txscript.WithScriptAllocSize(P2PKHSize),
3✔
129
        )
3✔
130

3✔
131
        bldr.AddOp(txscript.OP_DUP)
3✔
132
        bldr.AddOp(txscript.OP_HASH160)
3✔
133
        pkhash := btcutil.Hash160(pubkey)
3✔
134
        bldr.AddData(pkhash)
3✔
135
        bldr.AddOp(txscript.OP_EQUALVERIFY)
3✔
136
        bldr.AddOp(txscript.OP_CHECKSIG)
3✔
137
        return bldr.Script()
3✔
138
}
3✔
139

140
// GenerateUnknownWitness generates the maximum-sized witness public key script
141
// consisting of a version push and a 40-byte data push.
142
func GenerateUnknownWitness() ([]byte, error) {
3✔
143
        bldr := txscript.NewScriptBuilder()
3✔
144

3✔
145
        bldr.AddOp(txscript.OP_0)
3✔
146
        witnessScript := make([]byte, 40)
3✔
147
        bldr.AddData(witnessScript)
3✔
148
        return bldr.Script()
3✔
149
}
3✔
150

151
// GenMultiSigScript generates the non-p2sh'd multisig script for 2 of 2
152
// pubkeys.
153
func GenMultiSigScript(aPub, bPub []byte) ([]byte, error) {
3✔
154
        if len(aPub) != 33 || len(bPub) != 33 {
3✔
155
                return nil, fmt.Errorf("pubkey size error: compressed " +
×
156
                        "pubkeys only")
×
157
        }
×
158

159
        // Swap to sort pubkeys if needed. Keys are sorted in lexicographical
160
        // order. The signatures within the scriptSig must also adhere to the
161
        // order, ensuring that the signatures for each public key appears in
162
        // the proper order on the stack.
163
        if bytes.Compare(aPub, bPub) == 1 {
6✔
164
                aPub, bPub = bPub, aPub
3✔
165
        }
3✔
166

167
        bldr := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
168
                MultiSigSize,
3✔
169
        ))
3✔
170
        bldr.AddOp(txscript.OP_2)
3✔
171
        bldr.AddData(aPub) // Add both pubkeys (sorted).
3✔
172
        bldr.AddData(bPub)
3✔
173
        bldr.AddOp(txscript.OP_2)
3✔
174
        bldr.AddOp(txscript.OP_CHECKMULTISIG)
3✔
175
        return bldr.Script()
3✔
176
}
177

178
// GenFundingPkScript creates a redeem script, and its matching p2wsh
179
// output for the funding transaction.
180
func GenFundingPkScript(aPub, bPub []byte, amt int64) ([]byte, *wire.TxOut, error) {
3✔
181
        // As a sanity check, ensure that the passed amount is above zero.
3✔
182
        if amt <= 0 {
3✔
183
                return nil, nil, fmt.Errorf("can't create FundTx script with " +
×
184
                        "zero, or negative coins")
×
185
        }
×
186

187
        // First, create the 2-of-2 multi-sig script itself.
188
        witnessScript, err := GenMultiSigScript(aPub, bPub)
3✔
189
        if err != nil {
3✔
190
                return nil, nil, err
×
191
        }
×
192

193
        // With the 2-of-2 script in had, generate a p2wsh script which pays
194
        // to the funding script.
195
        pkScript, err := WitnessScriptHash(witnessScript)
3✔
196
        if err != nil {
3✔
197
                return nil, nil, err
×
198
        }
×
199

200
        return witnessScript, wire.NewTxOut(amt, pkScript), nil
3✔
201
}
202

203
// GenTaprootFundingScript constructs the taproot-native funding output that
204
// uses MuSig2 to create a single aggregated key to anchor the channel.
205
func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
206
        amt int64, tapscriptRoot fn.Option[chainhash.Hash]) ([]byte,
207
        *wire.TxOut, error) {
3✔
208

3✔
209
        muSig2Opt := musig2.WithBIP86KeyTweak()
3✔
210
        tapscriptRoot.WhenSome(func(scriptRoot chainhash.Hash) {
3✔
UNCOV
211
                muSig2Opt = musig2.WithTaprootKeyTweak(scriptRoot[:])
×
UNCOV
212
        })
×
213

214
        // Similar to the existing p2wsh funding script, we'll always make sure
215
        // we sort the keys before any major operations. In order to ensure
216
        // that there's no other way this output can be spent, we'll use a BIP
217
        // 86 tweak here during aggregation, unless the user has explicitly
218
        // specified a tapscript root.
219
        combinedKey, _, _, err := musig2.AggregateKeys(
3✔
220
                []*btcec.PublicKey{aPub, bPub}, true, muSig2Opt,
3✔
221
        )
3✔
222
        if err != nil {
3✔
223
                return nil, nil, fmt.Errorf("unable to combine keys: %w", err)
×
224
        }
×
225

226
        // Now that we have the combined key, we can create a taproot pkScript
227
        // from this, and then make the txOut given the amount.
228
        pkScript, err := PayToTaprootScript(combinedKey.FinalKey)
3✔
229
        if err != nil {
3✔
230
                return nil, nil, fmt.Errorf("unable to make taproot "+
×
231
                        "pkscript: %w", err)
×
232
        }
×
233

234
        txOut := wire.NewTxOut(amt, pkScript)
3✔
235

3✔
236
        // For the "witness program" we just return the raw pkScript since the
3✔
237
        // output we create can _only_ be spent with a MuSig2 signature.
3✔
238
        return pkScript, txOut, nil
3✔
239
}
240

241
// SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh
242
// multi-sig output.
243
func SpendMultiSig(witnessScript, pubA []byte, sigA Signature,
244
        pubB []byte, sigB Signature) [][]byte {
3✔
245

3✔
246
        witness := make([][]byte, 4)
3✔
247

3✔
248
        // When spending a p2wsh multi-sig script, rather than an OP_0, we add
3✔
249
        // a nil stack element to eat the extra pop.
3✔
250
        witness[0] = nil
3✔
251

3✔
252
        // When initially generating the witnessScript, we sorted the serialized
3✔
253
        // public keys in descending order. So we do a quick comparison in order
3✔
254
        // ensure the signatures appear on the Script Virtual Machine stack in
3✔
255
        // the correct order.
3✔
256
        if bytes.Compare(pubA, pubB) == 1 {
6✔
257
                witness[1] = append(sigB.Serialize(), byte(txscript.SigHashAll))
3✔
258
                witness[2] = append(sigA.Serialize(), byte(txscript.SigHashAll))
3✔
259
        } else {
6✔
260
                witness[1] = append(sigA.Serialize(), byte(txscript.SigHashAll))
3✔
261
                witness[2] = append(sigB.Serialize(), byte(txscript.SigHashAll))
3✔
262
        }
3✔
263

264
        // Finally, add the preimage as the last witness element.
265
        witness[3] = witnessScript
3✔
266

3✔
267
        return witness
3✔
268
}
269

270
// FindScriptOutputIndex finds the index of the public key script output
271
// matching 'script'. Additionally, a boolean is returned indicating if a
272
// matching output was found at all.
273
//
274
// NOTE: The search stops after the first matching script is found.
275
func FindScriptOutputIndex(tx *wire.MsgTx, script []byte) (bool, uint32) {
3✔
276
        found := false
3✔
277
        index := uint32(0)
3✔
278
        for i, txOut := range tx.TxOut {
6✔
279
                if bytes.Equal(txOut.PkScript, script) {
6✔
280
                        found = true
3✔
281
                        index = uint32(i)
3✔
282
                        break
3✔
283
                }
284
        }
285

286
        return found, index
3✔
287
}
288

289
// Ripemd160H calculates the ripemd160 of the passed byte slice. This is used to
290
// calculate the intermediate hash for payment pre-images. Payment hashes are
291
// the result of ripemd160(sha256(paymentPreimage)). As a result, the value
292
// passed in should be the sha256 of the payment hash.
293
func Ripemd160H(d []byte) []byte {
3✔
294
        h := ripemd160.New()
3✔
295
        h.Write(d)
3✔
296
        return h.Sum(nil)
3✔
297
}
3✔
298

299
// SenderHTLCScript constructs the public key script for an outgoing HTLC
300
// output payment for the sender's version of the commitment transaction. The
301
// possible script paths from this output include:
302
//
303
//   - The sender timing out the HTLC using the second level HTLC timeout
304
//     transaction.
305
//   - The receiver of the HTLC claiming the output on-chain with the payment
306
//     preimage.
307
//   - The receiver of the HTLC sweeping all the funds in the case that a
308
//     revoked commitment transaction bearing this HTLC was broadcast.
309
//
310
// If confirmedSpend=true, a 1 OP_CSV check will be added to the non-revocation
311
// cases, to allow sweeping only after confirmation.
312
//
313
// Possible Input Scripts:
314
//
315
//        SENDR: <0> <sendr sig>  <recvr sig> <0> (spend using HTLC timeout transaction)
316
//        RECVR: <recvr sig>  <preimage>
317
//        REVOK: <revoke sig> <revoke key>
318
//         * receiver revoke
319
//
320
// Offered HTLC Output Script:
321
//
322
//         OP_DUP OP_HASH160 <revocation key hash160> OP_EQUAL
323
//         OP_IF
324
//                OP_CHECKSIG
325
//         OP_ELSE
326
//                <recv htlc key>
327
//                OP_SWAP OP_SIZE 32 OP_EQUAL
328
//                OP_NOTIF
329
//                    OP_DROP 2 OP_SWAP <sender htlc key> 2 OP_CHECKMULTISIG
330
//                OP_ELSE
331
//                    OP_HASH160 <ripemd160(payment hash)> OP_EQUALVERIFY
332
//                    OP_CHECKSIG
333
//                OP_ENDIF
334
//                [1 OP_CHECKSEQUENCEVERIFY OP_DROP] <- if allowing confirmed
335
//                spend only.
336
//         OP_ENDIF
337
func SenderHTLCScript(senderHtlcKey, receiverHtlcKey,
338
        revocationKey *btcec.PublicKey, paymentHash []byte,
339
        confirmedSpend bool) ([]byte, error) {
3✔
340

3✔
341
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
342
                OfferedHtlcScriptSizeConfirmed,
3✔
343
        ))
3✔
344

3✔
345
        // The opening operations are used to determine if this is the receiver
3✔
346
        // of the HTLC attempting to sweep all the funds due to a contract
3✔
347
        // breach. In this case, they'll place the revocation key at the top of
3✔
348
        // the stack.
3✔
349
        builder.AddOp(txscript.OP_DUP)
3✔
350
        builder.AddOp(txscript.OP_HASH160)
3✔
351
        builder.AddData(btcutil.Hash160(revocationKey.SerializeCompressed()))
3✔
352
        builder.AddOp(txscript.OP_EQUAL)
3✔
353

3✔
354
        // If the hash matches, then this is the revocation clause. The output
3✔
355
        // can be spent if the check sig operation passes.
3✔
356
        builder.AddOp(txscript.OP_IF)
3✔
357
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
358

3✔
359
        // Otherwise, this may either be the receiver of the HTLC claiming with
3✔
360
        // the pre-image, or the sender of the HTLC sweeping the output after
3✔
361
        // it has timed out.
3✔
362
        builder.AddOp(txscript.OP_ELSE)
3✔
363

3✔
364
        // We'll do a bit of set up by pushing the receiver's key on the top of
3✔
365
        // the stack. This will be needed later if we decide that this is the
3✔
366
        // sender activating the time out clause with the HTLC timeout
3✔
367
        // transaction.
3✔
368
        builder.AddData(receiverHtlcKey.SerializeCompressed())
3✔
369

3✔
370
        // Atm, the top item of the stack is the receiverKey's so we use a swap
3✔
371
        // to expose what is either the payment pre-image or a signature.
3✔
372
        builder.AddOp(txscript.OP_SWAP)
3✔
373

3✔
374
        // With the top item swapped, check if it's 32 bytes. If so, then this
3✔
375
        // *may* be the payment pre-image.
3✔
376
        builder.AddOp(txscript.OP_SIZE)
3✔
377
        builder.AddInt64(32)
3✔
378
        builder.AddOp(txscript.OP_EQUAL)
3✔
379

3✔
380
        // If it isn't then this might be the sender of the HTLC activating the
3✔
381
        // time out clause.
3✔
382
        builder.AddOp(txscript.OP_NOTIF)
3✔
383

3✔
384
        // We'll drop the OP_IF return value off the top of the stack so we can
3✔
385
        // reconstruct the multi-sig script used as an off-chain covenant. If
3✔
386
        // two valid signatures are provided, then the output will be deemed as
3✔
387
        // spendable.
3✔
388
        builder.AddOp(txscript.OP_DROP)
3✔
389
        builder.AddOp(txscript.OP_2)
3✔
390
        builder.AddOp(txscript.OP_SWAP)
3✔
391
        builder.AddData(senderHtlcKey.SerializeCompressed())
3✔
392
        builder.AddOp(txscript.OP_2)
3✔
393
        builder.AddOp(txscript.OP_CHECKMULTISIG)
3✔
394

3✔
395
        // Otherwise, then the only other case is that this is the receiver of
3✔
396
        // the HTLC sweeping it on-chain with the payment pre-image.
3✔
397
        builder.AddOp(txscript.OP_ELSE)
3✔
398

3✔
399
        // Hash the top item of the stack and compare it with the hash160 of
3✔
400
        // the payment hash, which is already the sha256 of the payment
3✔
401
        // pre-image. By using this little trick we're able to save space
3✔
402
        // on-chain as the witness includes a 20-byte hash rather than a
3✔
403
        // 32-byte hash.
3✔
404
        builder.AddOp(txscript.OP_HASH160)
3✔
405
        builder.AddData(Ripemd160H(paymentHash))
3✔
406
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
407

3✔
408
        // This checks the receiver's signature so that a third party with
3✔
409
        // knowledge of the payment preimage still cannot steal the output.
3✔
410
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
411

3✔
412
        // Close out the OP_IF statement above.
3✔
413
        builder.AddOp(txscript.OP_ENDIF)
3✔
414

3✔
415
        // Add 1 block CSV delay if a confirmation is required for the
3✔
416
        // non-revocation clauses.
3✔
417
        if confirmedSpend {
6✔
418
                builder.AddOp(txscript.OP_1)
3✔
419
                builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
420
                builder.AddOp(txscript.OP_DROP)
3✔
421
        }
3✔
422

423
        // Close out the OP_IF statement at the top of the script.
424
        builder.AddOp(txscript.OP_ENDIF)
3✔
425

3✔
426
        return builder.Script()
3✔
427
}
428

429
// SenderHtlcSpendRevokeWithKey constructs a valid witness allowing the receiver of an
430
// HTLC to claim the output with knowledge of the revocation private key in the
431
// scenario that the sender of the HTLC broadcasts a previously revoked
432
// commitment transaction. A valid spend requires knowledge of the private key
433
// that corresponds to their revocation base point and also the private key from
434
// the per commitment point, and a valid signature under the combined public
435
// key.
436
func SenderHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
UNCOV
437
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
438

×
UNCOV
439
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
440
        if err != nil {
×
441
                return nil, err
×
442
        }
×
443

444
        // The stack required to sweep a revoke HTLC output consists simply of
445
        // the exact witness stack as one of a regular p2wkh spend. The only
446
        // difference is that the keys used were derived in an adversarial
447
        // manner in order to encode the revocation contract into a sig+key
448
        // pair.
UNCOV
449
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
450
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
451
        witnessStack[1] = revokeKey.SerializeCompressed()
×
UNCOV
452
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
453

×
UNCOV
454
        return witnessStack, nil
×
455
}
456

457
// SenderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
458
// HTLC to claim the output with knowledge of the revocation private key in the
459
// scenario that the sender of the HTLC broadcasts a previously revoked
460
// commitment transaction.  This method first derives the appropriate revocation
461
// key, and requires that the provided SignDescriptor has a local revocation
462
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
463
// respectively.
464
func SenderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
465
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
466

×
UNCOV
467
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
468
        if err != nil {
×
469
                return nil, err
×
470
        }
×
471

UNCOV
472
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
×
473
}
474

475
// IsHtlcSpendRevoke is used to determine if the passed spend is spending a
476
// HTLC output using the revocation key.
477
func IsHtlcSpendRevoke(txIn *wire.TxIn, signDesc *SignDescriptor) (
478
        bool, error) {
3✔
479

3✔
480
        // For taproot channels, the revocation path only has a single witness,
3✔
481
        // as that's the key spend path.
3✔
482
        isTaproot := txscript.IsPayToTaproot(signDesc.Output.PkScript)
3✔
483
        if isTaproot {
6✔
484
                return len(txIn.Witness) == 1, nil
3✔
485
        }
3✔
486

UNCOV
487
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
488
        if err != nil {
×
489
                return false, err
×
490
        }
×
491

UNCOV
492
        if len(txIn.Witness) == 3 &&
×
UNCOV
493
                bytes.Equal(txIn.Witness[1], revokeKey.SerializeCompressed()) {
×
UNCOV
494

×
UNCOV
495
                return true, nil
×
UNCOV
496
        }
×
497

UNCOV
498
        return false, nil
×
499
}
500

501
// SenderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
502
// HTLC to redeem the pending output in the scenario that the sender broadcasts
503
// their version of the commitment transaction. A valid spend requires
504
// knowledge of the payment preimage, and a valid signature under the receivers
505
// public key.
506
func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
507
        sweepTx *wire.MsgTx, paymentPreimage []byte) (wire.TxWitness, error) {
3✔
508

3✔
509
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
510
        if err != nil {
3✔
511
                return nil, err
×
512
        }
×
513

514
        // The stack required to spend this output is simply the signature
515
        // generated above under the receiver's public key, and the payment
516
        // pre-image.
517
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
518
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
519
        witnessStack[1] = paymentPreimage
3✔
520
        witnessStack[2] = signDesc.WitnessScript
3✔
521

3✔
522
        return witnessStack, nil
3✔
523
}
524

525
// SenderHtlcSpendTimeout constructs a valid witness allowing the sender of an
526
// HTLC to activate the time locked covenant clause of a soon to be expired
527
// HTLC.  This script simply spends the multi-sig output using the
528
// pre-generated HTLC timeout transaction.
529
func SenderHtlcSpendTimeout(receiverSig Signature,
530
        receiverSigHash txscript.SigHashType, signer Signer,
531
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (
532
        wire.TxWitness, error) {
3✔
533

3✔
534
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
3✔
535
        if err != nil {
3✔
536
                return nil, err
×
537
        }
×
538

539
        // We place a zero as the first item of the evaluated witness stack in
540
        // order to force Script execution to the HTLC timeout clause. The
541
        // second zero is required to consume the extra pop due to a bug in the
542
        // original OP_CHECKMULTISIG.
543
        witnessStack := wire.TxWitness(make([][]byte, 5))
3✔
544
        witnessStack[0] = nil
3✔
545
        witnessStack[1] = append(receiverSig.Serialize(), byte(receiverSigHash))
3✔
546
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
547
        witnessStack[3] = nil
3✔
548
        witnessStack[4] = signDesc.WitnessScript
3✔
549

3✔
550
        return witnessStack, nil
3✔
551
}
552

553
// SenderHTLCTapLeafTimeout returns the full tapscript leaf for the timeout
554
// path of the sender HTLC. This is a small script that allows the sender to
555
// timeout the HTLC after a period of time:
556
//
557
//        <local_key> OP_CHECKSIGVERIFY
558
//        <remote_key> OP_CHECKSIG
559
func SenderHTLCTapLeafTimeout(senderHtlcKey,
560
        receiverHtlcKey *btcec.PublicKey) (txscript.TapLeaf, error) {
3✔
561

3✔
562
        builder := txscript.NewScriptBuilder()
3✔
563

3✔
564
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
3✔
565
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
566
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
3✔
567
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
568

3✔
569
        timeoutLeafScript, err := builder.Script()
3✔
570
        if err != nil {
3✔
571
                return txscript.TapLeaf{}, err
×
572
        }
×
573

574
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
3✔
575
}
576

577
// SenderHTLCTapLeafSuccess returns the full tapscript leaf for the success
578
// path of the sender HTLC. This is a small script that allows the receiver to
579
// redeem the HTLC with a pre-image:
580
//
581
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
582
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
583
//        <remote_htlcpubkey> OP_CHECKSIG
584
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
585
func SenderHTLCTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
586
        paymentHash []byte) (txscript.TapLeaf, error) {
3✔
587

3✔
588
        builder := txscript.NewScriptBuilder()
3✔
589

3✔
590
        // Check that the pre-image is 32 bytes as required.
3✔
591
        builder.AddOp(txscript.OP_SIZE)
3✔
592
        builder.AddInt64(32)
3✔
593
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
594

3✔
595
        // Check that the specified pre-image matches what we hard code into
3✔
596
        // the script.
3✔
597
        builder.AddOp(txscript.OP_HASH160)
3✔
598
        builder.AddData(Ripemd160H(paymentHash))
3✔
599
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
600

3✔
601
        // Verify the remote party's signature, then make them wait 1 block
3✔
602
        // after confirmation to properly sweep.
3✔
603
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
3✔
604
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
605
        builder.AddOp(txscript.OP_1)
3✔
606
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
607
        builder.AddOp(txscript.OP_DROP)
3✔
608

3✔
609
        successLeafScript, err := builder.Script()
3✔
610
        if err != nil {
3✔
611
                return txscript.TapLeaf{}, err
×
612
        }
×
613

614
        return txscript.NewBaseTapLeaf(successLeafScript), nil
3✔
615
}
616

617
// htlcType is an enum value that denotes what type of HTLC script this is.
618
type htlcType uint8
619

620
const (
621
        // htlcLocalIncoming represents an incoming HTLC on the local
622
        // commitment transaction.
623
        htlcLocalIncoming htlcType = iota
624

625
        // htlcLocalOutgoing represents an outgoing HTLC on the local
626
        // commitment transaction.
627
        htlcLocalOutgoing
628

629
        // htlcRemoteIncoming represents an incoming HTLC on the remote
630
        // commitment transaction.
631
        htlcRemoteIncoming
632

633
        // htlcRemoteOutgoing represents an outgoing HTLC on the remote
634
        // commitment transaction.
635
        htlcRemoteOutgoing
636
)
637

638
// HtlcScriptTree holds the taproot output key, as well as the two script path
639
// leaves that every taproot HTLC script depends on.
640
type HtlcScriptTree struct {
641
        ScriptTree
642

643
        // SuccessTapLeaf is the tapleaf for the redemption path.
644
        SuccessTapLeaf txscript.TapLeaf
645

646
        // TimeoutTapLeaf is the tapleaf for the timeout path.
647
        TimeoutTapLeaf txscript.TapLeaf
648

649
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
650
        // HTLC script tree with new spend paths, or just as extra commitment
651
        // space. When present, this leaf will always be in the right-most area
652
        // of the tapscript tree.
653
        AuxLeaf AuxTapLeaf
654

655
        // htlcType is the type of HTLC script this is.
656
        htlcType htlcType
657
}
658

659
// WitnessScriptToSign returns the witness script that we'll use when signing
660
// for the remote party, and also verifying signatures on our transactions. As
661
// an example, when we create an outgoing HTLC for the remote party, we want to
662
// sign the success path for them, so we'll return the success path leaf.
663
func (h *HtlcScriptTree) WitnessScriptToSign() []byte {
3✔
664
        switch h.htlcType {
3✔
665
        // For incoming HLTCs on our local commitment, we care about verifying
666
        // the success path.
667
        case htlcLocalIncoming:
3✔
668
                return h.SuccessTapLeaf.Script
3✔
669

670
        // For incoming HTLCs on the remote party's commitment, we want to sign
671
        // the timeout path for them.
672
        case htlcRemoteIncoming:
3✔
673
                return h.TimeoutTapLeaf.Script
3✔
674

675
        // For outgoing HTLCs on our local commitment, we want to verify the
676
        // timeout path.
677
        case htlcLocalOutgoing:
3✔
678
                return h.TimeoutTapLeaf.Script
3✔
679

680
        // For outgoing HTLCs on the remote party's commitment, we want to sign
681
        // the success path for them.
682
        case htlcRemoteOutgoing:
3✔
683
                return h.SuccessTapLeaf.Script
3✔
684

685
        default:
×
686
                panic(fmt.Sprintf("unknown htlc type: %v", h.htlcType))
×
687
        }
688
}
689

690
// WitnessScriptForPath returns the witness script for the given spending path.
691
// An error is returned if the path is unknown.
692
func (h *HtlcScriptTree) WitnessScriptForPath(path ScriptPath) ([]byte, error) {
3✔
693
        switch path {
3✔
694
        case ScriptPathSuccess:
3✔
695
                return h.SuccessTapLeaf.Script, nil
3✔
696
        case ScriptPathTimeout:
3✔
697
                return h.TimeoutTapLeaf.Script, nil
3✔
698
        default:
×
699
                return nil, fmt.Errorf("unknown script path: %v", path)
×
700
        }
701
}
702

703
// CtrlBlockForPath returns the control block for the given spending path. For
704
// script types that don't have a control block, nil is returned.
705
func (h *HtlcScriptTree) CtrlBlockForPath(
706
        path ScriptPath) (*txscript.ControlBlock, error) {
3✔
707

3✔
708
        switch path {
3✔
709
        case ScriptPathSuccess:
3✔
710
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
711
                        h.SuccessTapLeaf.Script, h.InternalKey,
3✔
712
                        h.TapscriptTree,
3✔
713
                )), nil
3✔
714
        case ScriptPathTimeout:
3✔
715
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
716
                        h.TimeoutTapLeaf.Script, h.InternalKey,
3✔
717
                        h.TapscriptTree,
3✔
718
                )), nil
3✔
719
        default:
×
720
                return nil, fmt.Errorf("unknown script path: %v", path)
×
721
        }
722
}
723

724
// Tree returns the underlying ScriptTree of the HtlcScriptTree.
725
func (h *HtlcScriptTree) Tree() ScriptTree {
×
726
        return h.ScriptTree
×
727
}
×
728

729
// A compile time check to ensure HtlcScriptTree implements the
730
// TapscriptMultiplexer interface.
731
var _ TapscriptDescriptor = (*HtlcScriptTree)(nil)
732

733
// senderHtlcTapScriptTree builds the tapscript tree which is used to anchor
734
// the HTLC key for HTLCs on the sender's commitment.
735
func senderHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
736
        revokeKey *btcec.PublicKey, payHash []byte, hType htlcType,
737
        auxLeaf AuxTapLeaf) (*HtlcScriptTree, error) {
3✔
738

3✔
739
        // First, we'll obtain the tap leaves for both the success and timeout
3✔
740
        // path.
3✔
741
        successTapLeaf, err := SenderHTLCTapLeafSuccess(
3✔
742
                receiverHtlcKey, payHash,
3✔
743
        )
3✔
744
        if err != nil {
3✔
745
                return nil, err
×
746
        }
×
747
        timeoutTapLeaf, err := SenderHTLCTapLeafTimeout(
3✔
748
                senderHtlcKey, receiverHtlcKey,
3✔
749
        )
3✔
750
        if err != nil {
3✔
751
                return nil, err
×
752
        }
×
753

754
        tapLeaves := []txscript.TapLeaf{successTapLeaf, timeoutTapLeaf}
3✔
755
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
3✔
UNCOV
756
                tapLeaves = append(tapLeaves, l)
×
UNCOV
757
        })
×
758

759
        // With the two leaves obtained, we'll now make the tapscript tree,
760
        // then obtain the root from that
761
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
3✔
762

3✔
763
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
3✔
764

3✔
765
        // With the tapscript root obtained, we'll tweak the revocation key
3✔
766
        // with this value to obtain the key that HTLCs will be sent to.
3✔
767
        htlcKey := txscript.ComputeTaprootOutputKey(
3✔
768
                revokeKey, tapScriptRoot[:],
3✔
769
        )
3✔
770

3✔
771
        return &HtlcScriptTree{
3✔
772
                ScriptTree: ScriptTree{
3✔
773
                        TaprootKey:    htlcKey,
3✔
774
                        TapscriptTree: tapscriptTree,
3✔
775
                        TapscriptRoot: tapScriptRoot[:],
3✔
776
                        InternalKey:   revokeKey,
3✔
777
                },
3✔
778
                SuccessTapLeaf: successTapLeaf,
3✔
779
                TimeoutTapLeaf: timeoutTapLeaf,
3✔
780
                AuxLeaf:        auxLeaf,
3✔
781
                htlcType:       hType,
3✔
782
        }, nil
3✔
783
}
784

785
// SenderHTLCScriptTaproot constructs the taproot witness program (schnorr key)
786
// for an outgoing HTLC on the sender's version of the commitment transaction.
787
// This method returns the top level tweaked public key that commits to both
788
// the script paths. This is also known as an offered HTLC.
789
//
790
// The returned key commits to a tapscript tree with two possible paths:
791
//
792
//   - Timeout path:
793
//     <local_key> OP_CHECKSIGVERIFY
794
//     <remote_key> OP_CHECKSIG
795
//
796
//   - Success path:
797
//     OP_SIZE 32 OP_EQUALVERIFY
798
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
799
//     <remote_htlcpubkey> OP_CHECKSIG
800
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
801
//
802
// The timeout path can be spent with a witness of (sender timeout):
803
//
804
//        <receiver sig> <local sig> <timeout_script> <control_block>
805
//
806
// The success path can be spent with a valid control block, and a witness of
807
// (receiver redeem):
808
//
809
//        <receiver sig> <preimage> <success_script> <control_block>
810
//
811
// The top level keyspend key is the revocation key, which allows a defender to
812
// unilaterally spend the created output.
813
func SenderHTLCScriptTaproot(senderHtlcKey, receiverHtlcKey,
814
        revokeKey *btcec.PublicKey, payHash []byte,
815
        whoseCommit lntypes.ChannelParty, auxLeaf AuxTapLeaf) (*HtlcScriptTree,
816
        error) {
3✔
817

3✔
818
        var hType htlcType
3✔
819
        if whoseCommit.IsLocal() {
6✔
820
                hType = htlcLocalOutgoing
3✔
821
        } else {
6✔
822
                hType = htlcRemoteIncoming
3✔
823
        }
3✔
824

825
        // Given all the necessary parameters, we'll return the HTLC script
826
        // tree that includes the top level output script, as well as the two
827
        // tap leaf paths.
828
        return senderHtlcTapScriptTree(
3✔
829
                senderHtlcKey, receiverHtlcKey, revokeKey, payHash, hType,
3✔
830
                auxLeaf,
3✔
831
        )
3✔
832
}
833

834
// maybeAppendSighashType appends a sighash type to the end of a signature if
835
// the sighash type isn't sighash default.
836
func maybeAppendSighash(sig Signature, sigHash txscript.SigHashType) []byte {
3✔
837
        sigBytes := sig.Serialize()
3✔
838
        if sigHash == txscript.SigHashDefault {
6✔
839
                return sigBytes
3✔
840
        }
3✔
841

842
        return append(sigBytes, byte(sigHash))
3✔
843
}
844

845
// SenderHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
846
// sender taproot HTLC with the pre-image. The returned witness is valid and
847
// includes the control block required to spend the output. This is the offered
848
// HTLC claimed by the remote party.
849
func SenderHTLCScriptTaprootRedeem(signer Signer, signDesc *SignDescriptor,
850
        sweepTx *wire.MsgTx, preimage []byte, revokeKey *btcec.PublicKey,
851
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
852

3✔
853
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
854
        if err != nil {
3✔
855
                return nil, err
×
856
        }
×
857

858
        // In addition to the signature and the witness/leaf script, we also
859
        // need to make a control block proof using the tapscript tree.
860
        var ctrlBlock []byte
3✔
861
        if signDesc.ControlBlock == nil {
3✔
UNCOV
862
                successControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
863
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
864
                )
×
UNCOV
865

×
UNCOV
866
                ctrlBytes, err := successControlBlock.ToBytes()
×
UNCOV
867
                if err != nil {
×
868
                        return nil, err
×
869
                }
×
870

UNCOV
871
                ctrlBlock = ctrlBytes
×
872
        } else {
3✔
873
                ctrlBlock = signDesc.ControlBlock
3✔
874
        }
3✔
875

876
        // The final witness stack is:
877
        //  <receiver sig> <preimage> <success_script> <control_block>
878
        witnessStack := make(wire.TxWitness, 4)
3✔
879
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
880
        witnessStack[1] = preimage
3✔
881
        witnessStack[2] = signDesc.WitnessScript
3✔
882
        witnessStack[3] = ctrlBlock
3✔
883

3✔
884
        return witnessStack, nil
3✔
885
}
886

887
// SenderHTLCScriptTaprootTimeout creates a valid witness needed to timeout an
888
// HTLC on the sender's commitment transaction. The returned witness is valid
889
// and includes the control block required to spend the output. This is a
890
// timeout of the offered HTLC by the sender.
891
func SenderHTLCScriptTaprootTimeout(receiverSig Signature,
892
        receiverSigHash txscript.SigHashType, signer Signer,
893
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx,
894
        revokeKey *btcec.PublicKey,
895
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
896

3✔
897
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
3✔
898
        if err != nil {
3✔
899
                return nil, err
×
900
        }
×
901

902
        // With the sweep signature obtained, we'll obtain the control block
903
        // proof needed to perform a valid spend for the timeout path.
904
        var ctrlBlockBytes []byte
3✔
905
        if signDesc.ControlBlock == nil {
6✔
906
                timeoutControlBlock := MakeTaprootCtrlBlock(
3✔
907
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
3✔
908
                )
3✔
909
                ctrlBytes, err := timeoutControlBlock.ToBytes()
3✔
910
                if err != nil {
3✔
911
                        return nil, err
×
912
                }
×
913

914
                ctrlBlockBytes = ctrlBytes
3✔
915
        } else {
3✔
916
                ctrlBlockBytes = signDesc.ControlBlock
3✔
917
        }
3✔
918

919
        // The final witness stack is:
920
        //  <receiver sig> <local sig> <timeout_script> <control_block>
921
        witnessStack := make(wire.TxWitness, 4)
3✔
922
        witnessStack[0] = maybeAppendSighash(receiverSig, receiverSigHash)
3✔
923
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
924
        witnessStack[2] = signDesc.WitnessScript
3✔
925
        witnessStack[3] = ctrlBlockBytes
3✔
926

3✔
927
        return witnessStack, nil
3✔
928
}
929

930
// SenderHTLCScriptTaprootRevoke creates a valid witness needed to spend the
931
// revocation path of the HTLC. This uses a plain keyspend using the specified
932
// revocation key.
933
func SenderHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
934
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
935

3✔
936
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
937
        if err != nil {
3✔
938
                return nil, err
×
939
        }
×
940

941
        // The witness stack in this case is pretty simple: we only need to
942
        // specify the signature generated.
943
        witnessStack := make(wire.TxWitness, 1)
3✔
944
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
945

3✔
946
        return witnessStack, nil
3✔
947
}
948

949
// ReceiverHTLCScript constructs the public key script for an incoming HTLC
950
// output payment for the receiver's version of the commitment transaction. The
951
// possible execution paths from this script include:
952
//   - The receiver of the HTLC uses its second level HTLC transaction to
953
//     advance the state of the HTLC into the delay+claim state.
954
//   - The sender of the HTLC sweeps all the funds of the HTLC as a breached
955
//     commitment was broadcast.
956
//   - The sender of the HTLC sweeps the HTLC on-chain after the timeout period
957
//     of the HTLC has passed.
958
//
959
// If confirmedSpend=true, a 1 OP_CSV check will be added to the non-revocation
960
// cases, to allow sweeping only after confirmation.
961
//
962
// Possible Input Scripts:
963
//
964
//        RECVR: <0> <sender sig> <recvr sig> <preimage> (spend using HTLC success transaction)
965
//        REVOK: <sig> <key>
966
//        SENDR: <sig> 0
967
//
968
// Received HTLC Output Script:
969
//
970
//         OP_DUP OP_HASH160 <revocation key hash160> OP_EQUAL
971
//         OP_IF
972
//                 OP_CHECKSIG
973
//         OP_ELSE
974
//                <sendr htlc key>
975
//                OP_SWAP OP_SIZE 32 OP_EQUAL
976
//                OP_IF
977
//                    OP_HASH160 <ripemd160(payment hash)> OP_EQUALVERIFY
978
//                    2 OP_SWAP <recvr htlc key> 2 OP_CHECKMULTISIG
979
//                OP_ELSE
980
//                    OP_DROP <cltv expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
981
//                    OP_CHECKSIG
982
//                OP_ENDIF
983
//                [1 OP_CHECKSEQUENCEVERIFY OP_DROP] <- if allowing confirmed
984
//                spend only.
985
//         OP_ENDIF
986
func ReceiverHTLCScript(cltvExpiry uint32, senderHtlcKey,
987
        receiverHtlcKey, revocationKey *btcec.PublicKey,
988
        paymentHash []byte, confirmedSpend bool) ([]byte, error) {
3✔
989

3✔
990
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
991
                AcceptedHtlcScriptSizeConfirmed,
3✔
992
        ))
3✔
993

3✔
994
        // The opening operations are used to determine if this is the sender
3✔
995
        // of the HTLC attempting to sweep all the funds due to a contract
3✔
996
        // breach. In this case, they'll place the revocation key at the top of
3✔
997
        // the stack.
3✔
998
        builder.AddOp(txscript.OP_DUP)
3✔
999
        builder.AddOp(txscript.OP_HASH160)
3✔
1000
        builder.AddData(btcutil.Hash160(revocationKey.SerializeCompressed()))
3✔
1001
        builder.AddOp(txscript.OP_EQUAL)
3✔
1002

3✔
1003
        // If the hash matches, then this is the revocation clause. The output
3✔
1004
        // can be spent if the check sig operation passes.
3✔
1005
        builder.AddOp(txscript.OP_IF)
3✔
1006
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1007

3✔
1008
        // Otherwise, this may either be the receiver of the HTLC starting the
3✔
1009
        // claiming process via the second level HTLC success transaction and
3✔
1010
        // the pre-image, or the sender of the HTLC sweeping the output after
3✔
1011
        // it has timed out.
3✔
1012
        builder.AddOp(txscript.OP_ELSE)
3✔
1013

3✔
1014
        // We'll do a bit of set up by pushing the sender's key on the top of
3✔
1015
        // the stack. This will be needed later if we decide that this is the
3✔
1016
        // receiver transitioning the output to the claim state using their
3✔
1017
        // second-level HTLC success transaction.
3✔
1018
        builder.AddData(senderHtlcKey.SerializeCompressed())
3✔
1019

3✔
1020
        // Atm, the top item of the stack is the sender's key so we use a swap
3✔
1021
        // to expose what is either the payment pre-image or something else.
3✔
1022
        builder.AddOp(txscript.OP_SWAP)
3✔
1023

3✔
1024
        // With the top item swapped, check if it's 32 bytes. If so, then this
3✔
1025
        // *may* be the payment pre-image.
3✔
1026
        builder.AddOp(txscript.OP_SIZE)
3✔
1027
        builder.AddInt64(32)
3✔
1028
        builder.AddOp(txscript.OP_EQUAL)
3✔
1029

3✔
1030
        // If the item on the top of the stack is 32-bytes, then it is the
3✔
1031
        // proper size, so this indicates that the receiver of the HTLC is
3✔
1032
        // attempting to claim the output on-chain by transitioning the state
3✔
1033
        // of the HTLC to delay+claim.
3✔
1034
        builder.AddOp(txscript.OP_IF)
3✔
1035

3✔
1036
        // Next we'll hash the item on the top of the stack, if it matches the
3✔
1037
        // payment pre-image, then we'll continue. Otherwise, we'll end the
3✔
1038
        // script here as this is the invalid payment pre-image.
3✔
1039
        builder.AddOp(txscript.OP_HASH160)
3✔
1040
        builder.AddData(Ripemd160H(paymentHash))
3✔
1041
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
1042

3✔
1043
        // If the payment hash matches, then we'll also need to satisfy the
3✔
1044
        // multi-sig covenant by providing both signatures of the sender and
3✔
1045
        // receiver. If the convenient is met, then we'll allow the spending of
3✔
1046
        // this output, but only by the HTLC success transaction.
3✔
1047
        builder.AddOp(txscript.OP_2)
3✔
1048
        builder.AddOp(txscript.OP_SWAP)
3✔
1049
        builder.AddData(receiverHtlcKey.SerializeCompressed())
3✔
1050
        builder.AddOp(txscript.OP_2)
3✔
1051
        builder.AddOp(txscript.OP_CHECKMULTISIG)
3✔
1052

3✔
1053
        // Otherwise, this might be the sender of the HTLC attempting to sweep
3✔
1054
        // it on-chain after the timeout.
3✔
1055
        builder.AddOp(txscript.OP_ELSE)
3✔
1056

3✔
1057
        // We'll drop the extra item (which is the output from evaluating the
3✔
1058
        // OP_EQUAL) above from the stack.
3✔
1059
        builder.AddOp(txscript.OP_DROP)
3✔
1060

3✔
1061
        // With that item dropped off, we can now enforce the absolute
3✔
1062
        // lock-time required to timeout the HTLC. If the time has passed, then
3✔
1063
        // we'll proceed with a checksig to ensure that this is actually the
3✔
1064
        // sender of he original HTLC.
3✔
1065
        builder.AddInt64(int64(cltvExpiry))
3✔
1066
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
3✔
1067
        builder.AddOp(txscript.OP_DROP)
3✔
1068
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1069

3✔
1070
        // Close out the inner if statement.
3✔
1071
        builder.AddOp(txscript.OP_ENDIF)
3✔
1072

3✔
1073
        // Add 1 block CSV delay for non-revocation clauses if confirmation is
3✔
1074
        // required.
3✔
1075
        if confirmedSpend {
6✔
1076
                builder.AddOp(txscript.OP_1)
3✔
1077
                builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
1078
                builder.AddOp(txscript.OP_DROP)
3✔
1079
        }
3✔
1080

1081
        // Close out the outer if statement.
1082
        builder.AddOp(txscript.OP_ENDIF)
3✔
1083

3✔
1084
        return builder.Script()
3✔
1085
}
1086

1087
// ReceiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
1088
// an HTLC to redeem the conditional payment in the event that their commitment
1089
// transaction is broadcast. This clause transitions the state of the HLTC
1090
// output into the delay+claim state by activating the off-chain covenant bound
1091
// by the 2-of-2 multi-sig output. The HTLC success timeout transaction being
1092
// signed has a relative timelock delay enforced by its sequence number. This
1093
// delay give the sender of the HTLC enough time to revoke the output if this
1094
// is a breach commitment transaction.
1095
func ReceiverHtlcSpendRedeem(senderSig Signature,
1096
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1097
        signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
1098
        wire.TxWitness, error) {
3✔
1099

3✔
1100
        // First, we'll generate a signature for the HTLC success transaction.
3✔
1101
        // The signDesc should be signing with the public key used as the
3✔
1102
        // receiver's public key and also the correct single tweak.
3✔
1103
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
3✔
1104
        if err != nil {
3✔
1105
                return nil, err
×
1106
        }
×
1107

1108
        // The final witness stack is used the provide the script with the
1109
        // payment pre-image, and also execute the multi-sig clause after the
1110
        // pre-images matches. We add a nil item at the bottom of the stack in
1111
        // order to consume the extra pop within OP_CHECKMULTISIG.
1112
        witnessStack := wire.TxWitness(make([][]byte, 5))
3✔
1113
        witnessStack[0] = nil
3✔
1114
        witnessStack[1] = append(senderSig.Serialize(), byte(senderSigHash))
3✔
1115
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
1116
        witnessStack[3] = paymentPreimage
3✔
1117
        witnessStack[4] = signDesc.WitnessScript
3✔
1118

3✔
1119
        return witnessStack, nil
3✔
1120
}
1121

1122
// ReceiverHtlcSpendRevokeWithKey constructs a valid witness allowing the sender of an
1123
// HTLC within a previously revoked commitment transaction to re-claim the
1124
// pending funds in the case that the receiver broadcasts this revoked
1125
// commitment transaction.
1126
func ReceiverHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
UNCOV
1127
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1128

×
UNCOV
1129
        // First, we'll generate a signature for the sweep transaction.  The
×
UNCOV
1130
        // signDesc should be signing with the public key used as the fully
×
UNCOV
1131
        // derived revocation public key and also the correct double tweak
×
UNCOV
1132
        // value.
×
UNCOV
1133
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
1134
        if err != nil {
×
1135
                return nil, err
×
1136
        }
×
1137

1138
        // We place a zero, then one as the first items in the evaluated
1139
        // witness stack in order to force script execution to the HTLC
1140
        // revocation clause.
UNCOV
1141
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1142
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1143
        witnessStack[1] = revokeKey.SerializeCompressed()
×
UNCOV
1144
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1145

×
UNCOV
1146
        return witnessStack, nil
×
1147
}
1148

UNCOV
1149
func deriveRevokePubKey(signDesc *SignDescriptor) (*btcec.PublicKey, error) {
×
UNCOV
1150
        if signDesc.KeyDesc.PubKey == nil {
×
1151
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
1152
                        "KeyDesc pubkey")
×
1153
        }
×
1154

1155
        // Derive the revocation key using the local revocation base point and
1156
        // commitment point.
UNCOV
1157
        revokeKey := DeriveRevocationPubkey(
×
UNCOV
1158
                signDesc.KeyDesc.PubKey,
×
UNCOV
1159
                signDesc.DoubleTweak.PubKey(),
×
UNCOV
1160
        )
×
UNCOV
1161

×
UNCOV
1162
        return revokeKey, nil
×
1163
}
1164

1165
// ReceiverHtlcSpendRevoke constructs a valid witness allowing the sender of an
1166
// HTLC within a previously revoked commitment transaction to re-claim the
1167
// pending funds in the case that the receiver broadcasts this revoked
1168
// commitment transaction. This method first derives the appropriate revocation
1169
// key, and requires that the provided SignDescriptor has a local revocation
1170
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
1171
// respectively.
1172
func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1173
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1174

×
UNCOV
1175
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
1176
        if err != nil {
×
1177
                return nil, err
×
1178
        }
×
1179

UNCOV
1180
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
×
1181
}
1182

1183
// ReceiverHtlcSpendTimeout constructs a valid witness allowing the sender of
1184
// an HTLC to recover the pending funds after an absolute timeout in the
1185
// scenario that the receiver of the HTLC broadcasts their version of the
1186
// commitment transaction. If the caller has already set the lock time on the
1187
// spending transaction, than a value of -1 can be passed for the cltvExpiry
1188
// value.
1189
//
1190
// NOTE: The target input of the passed transaction MUST NOT have a final
1191
// sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
1192
func ReceiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
1193
        sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) {
3✔
1194

3✔
1195
        // If the caller set a proper timeout value, then we'll apply it
3✔
1196
        // directly to the transaction.
3✔
1197
        if cltvExpiry != -1 {
3✔
UNCOV
1198
                // The HTLC output has an absolute time period before we are
×
UNCOV
1199
                // permitted to recover the pending funds. Therefore we need to
×
UNCOV
1200
                // set the locktime on this sweeping transaction in order to
×
UNCOV
1201
                // pass Script verification.
×
UNCOV
1202
                sweepTx.LockTime = uint32(cltvExpiry)
×
UNCOV
1203
        }
×
1204

1205
        // With the lock time on the transaction set, we'll not generate a
1206
        // signature for the sweep transaction. The passed sign descriptor
1207
        // should be created using the raw public key of the sender (w/o the
1208
        // single tweak applied), and the single tweak set to the proper value
1209
        // taking into account the current state's point.
1210
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1211
        if err != nil {
3✔
1212
                return nil, err
×
1213
        }
×
1214

1215
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
1216
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
1217
        witnessStack[1] = nil
3✔
1218
        witnessStack[2] = signDesc.WitnessScript
3✔
1219

3✔
1220
        return witnessStack, nil
3✔
1221
}
1222

1223
// ReceiverHtlcTapLeafTimeout returns the full tapscript leaf for the timeout
1224
// path of the sender HTLC. This is a small script that allows the sender
1225
// timeout the HTLC after expiry:
1226
//
1227
//        <sender_htlcpubkey> OP_CHECKSIG
1228
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
1229
//        <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1230
func ReceiverHtlcTapLeafTimeout(senderHtlcKey *btcec.PublicKey,
1231
        cltvExpiry uint32) (txscript.TapLeaf, error) {
3✔
1232

3✔
1233
        builder := txscript.NewScriptBuilder()
3✔
1234

3✔
1235
        // The first part of the script will verify a signature from the
3✔
1236
        // sender authorizing the spend (the timeout).
3✔
1237
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
3✔
1238
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1239
        builder.AddOp(txscript.OP_1)
3✔
1240
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
1241
        builder.AddOp(txscript.OP_DROP)
3✔
1242

3✔
1243
        // The second portion will ensure that the CLTV expiry on the spending
3✔
1244
        // transaction is correct.
3✔
1245
        builder.AddInt64(int64(cltvExpiry))
3✔
1246
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
3✔
1247
        builder.AddOp(txscript.OP_DROP)
3✔
1248

3✔
1249
        timeoutLeafScript, err := builder.Script()
3✔
1250
        if err != nil {
3✔
1251
                return txscript.TapLeaf{}, err
×
1252
        }
×
1253

1254
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
3✔
1255
}
1256

1257
// ReceiverHtlcTapLeafSuccess returns the full tapscript leaf for the success
1258
// path for an HTLC on the receiver's commitment transaction. This script
1259
// allows the receiver to redeem an HTLC with knowledge of the preimage:
1260
//
1261
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
1262
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1263
//        <receiver_htlcpubkey> OP_CHECKSIGVERIFY
1264
//        <sender_htlcpubkey> OP_CHECKSIG
1265
func ReceiverHtlcTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
1266
        senderHtlcKey *btcec.PublicKey,
1267
        paymentHash []byte) (txscript.TapLeaf, error) {
3✔
1268

3✔
1269
        builder := txscript.NewScriptBuilder()
3✔
1270

3✔
1271
        // Check that the pre-image is 32 bytes as required.
3✔
1272
        builder.AddOp(txscript.OP_SIZE)
3✔
1273
        builder.AddInt64(32)
3✔
1274
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
1275

3✔
1276
        // Check that the specified pre-image matches what we hard code into
3✔
1277
        // the script.
3✔
1278
        builder.AddOp(txscript.OP_HASH160)
3✔
1279
        builder.AddData(Ripemd160H(paymentHash))
3✔
1280
        builder.AddOp(txscript.OP_EQUALVERIFY)
3✔
1281

3✔
1282
        // Verify the "2-of-2" multi-sig that requires both parties to sign
3✔
1283
        // off.
3✔
1284
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
3✔
1285
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
1286
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
3✔
1287
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1288

3✔
1289
        successLeafScript, err := builder.Script()
3✔
1290
        if err != nil {
3✔
1291
                return txscript.TapLeaf{}, err
×
1292
        }
×
1293

1294
        return txscript.NewBaseTapLeaf(successLeafScript), nil
3✔
1295
}
1296

1297
// receiverHtlcTapScriptTree builds the tapscript tree which is used to anchor
1298
// the HTLC key for HTLCs on the receiver's commitment.
1299
func receiverHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
1300
        revokeKey *btcec.PublicKey, payHash []byte, cltvExpiry uint32,
1301
        hType htlcType, auxLeaf AuxTapLeaf) (*HtlcScriptTree, error) {
3✔
1302

3✔
1303
        // First, we'll obtain the tap leaves for both the success and timeout
3✔
1304
        // path.
3✔
1305
        successTapLeaf, err := ReceiverHtlcTapLeafSuccess(
3✔
1306
                receiverHtlcKey, senderHtlcKey, payHash,
3✔
1307
        )
3✔
1308
        if err != nil {
3✔
1309
                return nil, err
×
1310
        }
×
1311
        timeoutTapLeaf, err := ReceiverHtlcTapLeafTimeout(
3✔
1312
                senderHtlcKey, cltvExpiry,
3✔
1313
        )
3✔
1314
        if err != nil {
3✔
1315
                return nil, err
×
1316
        }
×
1317

1318
        tapLeaves := []txscript.TapLeaf{timeoutTapLeaf, successTapLeaf}
3✔
1319
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
3✔
UNCOV
1320
                tapLeaves = append(tapLeaves, l)
×
UNCOV
1321
        })
×
1322

1323
        // With the two leaves obtained, we'll now make the tapscript tree,
1324
        // then obtain the root from that
1325
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
3✔
1326

3✔
1327
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
3✔
1328

3✔
1329
        // With the tapscript root obtained, we'll tweak the revocation key
3✔
1330
        // with this value to obtain the key that HTLCs will be sent to.
3✔
1331
        htlcKey := txscript.ComputeTaprootOutputKey(
3✔
1332
                revokeKey, tapScriptRoot[:],
3✔
1333
        )
3✔
1334

3✔
1335
        return &HtlcScriptTree{
3✔
1336
                ScriptTree: ScriptTree{
3✔
1337
                        TaprootKey:    htlcKey,
3✔
1338
                        TapscriptTree: tapscriptTree,
3✔
1339
                        TapscriptRoot: tapScriptRoot[:],
3✔
1340
                        InternalKey:   revokeKey,
3✔
1341
                },
3✔
1342
                SuccessTapLeaf: successTapLeaf,
3✔
1343
                TimeoutTapLeaf: timeoutTapLeaf,
3✔
1344
                AuxLeaf:        auxLeaf,
3✔
1345
                htlcType:       hType,
3✔
1346
        }, nil
3✔
1347
}
1348

1349
// ReceiverHTLCScriptTaproot constructs the taproot witness program (schnor
1350
// key) for an incoming HTLC on the receiver's version of the commitment
1351
// transaction. This method returns the top level tweaked public key that
1352
// commits to both the script paths. From the PoV of the receiver, this is an
1353
// accepted HTLC.
1354
//
1355
// The returned key commits to a tapscript tree with two possible paths:
1356
//
1357
//   - The timeout path:
1358
//     <remote_htlcpubkey> OP_CHECKSIG
1359
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
1360
//     <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1361
//
1362
//   - Success path:
1363
//     OP_SIZE 32 OP_EQUALVERIFY
1364
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1365
//     <local_htlcpubkey> OP_CHECKSIGVERIFY
1366
//     <remote_htlcpubkey> OP_CHECKSIG
1367
//
1368
// The timeout path can be spent with a witness of:
1369
//   - <sender sig> <timeout_script> <control_block>
1370
//
1371
// The success path can be spent with a witness of:
1372
//   - <sender sig> <receiver sig> <preimage> <success_script> <control_block>
1373
//
1374
// The top level keyspend key is the revocation key, which allows a defender to
1375
// unilaterally spend the created output. Both the final output key as well as
1376
// the tap leaf are returned.
1377
func ReceiverHTLCScriptTaproot(cltvExpiry uint32,
1378
        senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey,
1379
        payHash []byte, whoseCommit lntypes.ChannelParty,
1380
        auxLeaf AuxTapLeaf) (*HtlcScriptTree, error) {
3✔
1381

3✔
1382
        var hType htlcType
3✔
1383
        if whoseCommit.IsLocal() {
6✔
1384
                hType = htlcLocalIncoming
3✔
1385
        } else {
6✔
1386
                hType = htlcRemoteOutgoing
3✔
1387
        }
3✔
1388

1389
        // Given all the necessary parameters, we'll return the HTLC script
1390
        // tree that includes the top level output script, as well as the two
1391
        // tap leaf paths.
1392
        return receiverHtlcTapScriptTree(
3✔
1393
                senderHtlcKey, receiverHtlcKey, revocationKey, payHash,
3✔
1394
                cltvExpiry, hType, auxLeaf,
3✔
1395
        )
3✔
1396
}
1397

1398
// ReceiverHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
1399
// receiver taproot HTLC with the pre-image. The returned witness is valid and
1400
// includes the control block required to spend the output.
1401
func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
1402
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1403
        signer Signer, signDesc *SignDescriptor,
1404
        htlcSuccessTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1405
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
1406

3✔
1407
        // First, we'll generate a signature for the HTLC success transaction.
3✔
1408
        // The signDesc should be signing with the public key used as the
3✔
1409
        // receiver's public key and also the correct single tweak.
3✔
1410
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
3✔
1411
        if err != nil {
3✔
1412
                return nil, err
×
1413
        }
×
1414

1415
        // In addition to the signature and the witness/leaf script, we also
1416
        // need to make a control block proof using the tapscript tree.
1417
        var ctrlBlock []byte
3✔
1418
        if signDesc.ControlBlock == nil {
6✔
1419
                redeemControlBlock := MakeTaprootCtrlBlock(
3✔
1420
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
3✔
1421
                )
3✔
1422
                ctrlBytes, err := redeemControlBlock.ToBytes()
3✔
1423
                if err != nil {
3✔
1424
                        return nil, err
×
1425
                }
×
1426

1427
                ctrlBlock = ctrlBytes
3✔
1428
        } else {
3✔
1429
                ctrlBlock = signDesc.ControlBlock
3✔
1430
        }
3✔
1431

1432
        // The final witness stack is:
1433
        //  * <sender sig> <receiver sig> <preimage> <success_script>
1434
        //    <control_block>
1435
        witnessStack := wire.TxWitness(make([][]byte, 5))
3✔
1436
        witnessStack[0] = maybeAppendSighash(senderSig, senderSigHash)
3✔
1437
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
1438
        witnessStack[2] = paymentPreimage
3✔
1439
        witnessStack[3] = signDesc.WitnessScript
3✔
1440
        witnessStack[4] = ctrlBlock
3✔
1441

3✔
1442
        return witnessStack, nil
3✔
1443
}
1444

1445
// ReceiverHTLCScriptTaprootTimeout creates a valid witness needed to timeout
1446
// an HTLC on the receiver's commitment transaction after the timeout has
1447
// elapsed.
1448
func ReceiverHTLCScriptTaprootTimeout(signer Signer, signDesc *SignDescriptor,
1449
        sweepTx *wire.MsgTx, cltvExpiry int32, revokeKey *btcec.PublicKey,
1450
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
1451

3✔
1452
        // If the caller set a proper timeout value, then we'll apply it
3✔
1453
        // directly to the transaction.
3✔
1454
        //
3✔
1455
        // TODO(roasbeef): helper func
3✔
1456
        if cltvExpiry != -1 {
3✔
UNCOV
1457
                // The HTLC output has an absolute time period before we are
×
UNCOV
1458
                // permitted to recover the pending funds. Therefore we need to
×
UNCOV
1459
                // set the locktime on this sweeping transaction in order to
×
UNCOV
1460
                // pass Script verification.
×
UNCOV
1461
                sweepTx.LockTime = uint32(cltvExpiry)
×
UNCOV
1462
        }
×
1463

1464
        // With the lock time on the transaction set, we'll now generate a
1465
        // signature for the sweep transaction. The passed sign descriptor
1466
        // should be created using the raw public key of the sender (w/o the
1467
        // single tweak applied), and the single tweak set to the proper value
1468
        // taking into account the current state's point.
1469
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1470
        if err != nil {
3✔
1471
                return nil, err
×
1472
        }
×
1473

1474
        // In addition to the signature and the witness/leaf script, we also
1475
        // need to make a control block proof using the tapscript tree.
1476
        var ctrlBlock []byte
3✔
1477
        if signDesc.ControlBlock == nil {
3✔
UNCOV
1478
                timeoutControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
1479
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
1480
                )
×
UNCOV
1481
                ctrlBlock, err = timeoutControlBlock.ToBytes()
×
UNCOV
1482
                if err != nil {
×
1483
                        return nil, err
×
1484
                }
×
1485
        } else {
3✔
1486
                ctrlBlock = signDesc.ControlBlock
3✔
1487
        }
3✔
1488

1489
        // The final witness is pretty simple, we just need to present a valid
1490
        // signature for the script, and then provide the control block.
1491
        witnessStack := make(wire.TxWitness, 3)
3✔
1492
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
1493
        witnessStack[1] = signDesc.WitnessScript
3✔
1494
        witnessStack[2] = ctrlBlock
3✔
1495

3✔
1496
        return witnessStack, nil
3✔
1497
}
1498

1499
// ReceiverHTLCScriptTaprootRevoke creates a valid witness needed to spend the
1500
// revocation path of the HTLC from the PoV of the sender (offerer) of the
1501
// HTLC. This uses a plain keyspend using the specified revocation key.
1502
func ReceiverHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
1503
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
1504

3✔
1505
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1506
        if err != nil {
3✔
1507
                return nil, err
×
1508
        }
×
1509

1510
        // The witness stack in this case is pretty simple: we only need to
1511
        // specify the signature generated.
1512
        witnessStack := make(wire.TxWitness, 1)
3✔
1513
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
1514

3✔
1515
        return witnessStack, nil
3✔
1516
}
1517

1518
// SecondLevelHtlcScript is the uniform script that's used as the output for
1519
// the second-level HTLC transactions. The second level transaction act as a
1520
// sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1521
// spent in a particular way, and to a particular output.
1522
//
1523
// Possible Input Scripts:
1524
//
1525
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1526
//     state:
1527
//     <revoke sig> 1
1528
//
1529
//   - To claim and HTLC output, either with a pre-image or due to a timeout:
1530
//     <delay sig> 0
1531
//
1532
// Output Script:
1533
//
1534
//         OP_IF
1535
//                <revoke key>
1536
//         OP_ELSE
1537
//                <delay in blocks>
1538
//                OP_CHECKSEQUENCEVERIFY
1539
//                OP_DROP
1540
//                <delay key>
1541
//         OP_ENDIF
1542
//         OP_CHECKSIG
1543
//
1544
// TODO(roasbeef): possible renames for second-level
1545
//   - transition?
1546
//   - covenant output
1547
func SecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1548
        csvDelay uint32) ([]byte, error) {
3✔
1549

3✔
1550
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
1551
                ToLocalScriptSize,
3✔
1552
        ))
3✔
1553

3✔
1554
        // If this is the revocation clause for this script is to be executed,
3✔
1555
        // the spender will push a 1, forcing us to hit the true clause of this
3✔
1556
        // if statement.
3✔
1557
        builder.AddOp(txscript.OP_IF)
3✔
1558

3✔
1559
        // If this is the revocation case, then we'll push the revocation
3✔
1560
        // public key on the stack.
3✔
1561
        builder.AddData(revocationKey.SerializeCompressed())
3✔
1562

3✔
1563
        // Otherwise, this is either the sender or receiver of the HTLC
3✔
1564
        // attempting to claim the HTLC output.
3✔
1565
        builder.AddOp(txscript.OP_ELSE)
3✔
1566

3✔
1567
        // In order to give the other party time to execute the revocation
3✔
1568
        // clause above, we require a relative timeout to pass before the
3✔
1569
        // output can be spent.
3✔
1570
        builder.AddInt64(int64(csvDelay))
3✔
1571
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
1572
        builder.AddOp(txscript.OP_DROP)
3✔
1573

3✔
1574
        // If the relative timelock passes, then we'll add the delay key to the
3✔
1575
        // stack to ensure that we properly authenticate the spending party.
3✔
1576
        builder.AddData(delayKey.SerializeCompressed())
3✔
1577

3✔
1578
        // Close out the if statement.
3✔
1579
        builder.AddOp(txscript.OP_ENDIF)
3✔
1580

3✔
1581
        // In either case, we'll ensure that only either the party possessing
3✔
1582
        // the revocation private key, or the delay private key is able to
3✔
1583
        // spend this output.
3✔
1584
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1585

3✔
1586
        return builder.Script()
3✔
1587
}
3✔
1588

1589
// TODO(roasbeef): move all taproot stuff to new file?
1590

1591
// TaprootSecondLevelTapLeaf constructs the tap leaf used as the sole script
1592
// path for a second level HTLC spend.
1593
//
1594
// The final script used is:
1595
//
1596
//        <local_delay_key> OP_CHECKSIG
1597
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1598
func TaprootSecondLevelTapLeaf(delayKey *btcec.PublicKey,
1599
        csvDelay uint32) (txscript.TapLeaf, error) {
3✔
1600

3✔
1601
        builder := txscript.NewScriptBuilder()
3✔
1602

3✔
1603
        // Ensure the proper party can sign for this output.
3✔
1604
        builder.AddData(schnorr.SerializePubKey(delayKey))
3✔
1605
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1606

3✔
1607
        // Assuming the above passes, then we'll now ensure that the CSV delay
3✔
1608
        // has been upheld, dropping the int we pushed on. If the sig above is
3✔
1609
        // valid, then a 1 will be left on the stack.
3✔
1610
        builder.AddInt64(int64(csvDelay))
3✔
1611
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
1612
        builder.AddOp(txscript.OP_DROP)
3✔
1613

3✔
1614
        secondLevelLeafScript, err := builder.Script()
3✔
1615
        if err != nil {
3✔
1616
                return txscript.TapLeaf{}, err
×
1617
        }
×
1618

1619
        return txscript.NewBaseTapLeaf(secondLevelLeafScript), nil
3✔
1620
}
1621

1622
// SecondLevelHtlcTapscriptTree construct the indexed tapscript tree needed to
1623
// generate the tap tweak to create the final output and also control block.
1624
func SecondLevelHtlcTapscriptTree(delayKey *btcec.PublicKey, csvDelay uint32,
1625
        auxLeaf AuxTapLeaf) (*txscript.IndexedTapScriptTree, error) {
3✔
1626

3✔
1627
        // First grab the second level leaf script we need to create the top
3✔
1628
        // level output.
3✔
1629
        secondLevelTapLeaf, err := TaprootSecondLevelTapLeaf(delayKey, csvDelay)
3✔
1630
        if err != nil {
3✔
1631
                return nil, err
×
1632
        }
×
1633

1634
        tapLeaves := []txscript.TapLeaf{secondLevelTapLeaf}
3✔
1635
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
3✔
UNCOV
1636
                tapLeaves = append(tapLeaves, l)
×
UNCOV
1637
        })
×
1638

1639
        // Now that we have the sole second level script, we can create the
1640
        // tapscript tree that commits to both the leaves.
1641
        return txscript.AssembleTaprootScriptTree(tapLeaves...), nil
3✔
1642
}
1643

1644
// TaprootSecondLevelHtlcScript is the uniform script that's used as the output
1645
// for the second-level HTLC transaction. The second level transaction acts as
1646
// an off-chain 2-of-2 covenant that can only be spent a particular way and to
1647
// a particular output.
1648
//
1649
// Possible Input Scripts:
1650
//   - revocation sig
1651
//   - <local_delay_sig>
1652
//
1653
// The script main script lets the broadcaster spend after a delay the script
1654
// path:
1655
//
1656
//        <local_delay_key> OP_CHECKSIG
1657
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1658
//
1659
// The keyspend path require knowledge of the top level revocation private key.
1660
func TaprootSecondLevelHtlcScript(revokeKey, delayKey *btcec.PublicKey,
1661
        csvDelay uint32, auxLeaf AuxTapLeaf) (*btcec.PublicKey, error) {
×
1662

×
1663
        // First, we'll make the tapscript tree that commits to the redemption
×
1664
        // path.
×
1665
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
×
1666
                delayKey, csvDelay, auxLeaf,
×
1667
        )
×
1668
        if err != nil {
×
1669
                return nil, err
×
1670
        }
×
1671

1672
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
×
1673

×
1674
        // With the tapscript root obtained, we'll tweak the revocation key
×
1675
        // with this value to obtain the key that the second level spend will
×
1676
        // create.
×
1677
        redemptionKey := txscript.ComputeTaprootOutputKey(
×
1678
                revokeKey, tapScriptRoot[:],
×
1679
        )
×
1680

×
1681
        return redemptionKey, nil
×
1682
}
1683

1684
// SecondLevelScriptTree is a tapscript tree used to spend the second level
1685
// HTLC output after the CSV delay has passed.
1686
type SecondLevelScriptTree struct {
1687
        ScriptTree
1688

1689
        // SuccessTapLeaf is the tapleaf for the redemption path.
1690
        SuccessTapLeaf txscript.TapLeaf
1691

1692
        // AuxLeaf is an optional leaf that can be used to extend the script
1693
        // tree.
1694
        AuxLeaf AuxTapLeaf
1695
}
1696

1697
// TaprootSecondLevelScriptTree constructs the tapscript tree used to spend the
1698
// second level HTLC output.
1699
func TaprootSecondLevelScriptTree(revokeKey, delayKey *btcec.PublicKey,
1700
        csvDelay uint32, auxLeaf AuxTapLeaf) (*SecondLevelScriptTree, error) {
3✔
1701

3✔
1702
        // First, we'll make the tapscript tree that commits to the redemption
3✔
1703
        // path.
3✔
1704
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
3✔
1705
                delayKey, csvDelay, auxLeaf,
3✔
1706
        )
3✔
1707
        if err != nil {
3✔
1708
                return nil, err
×
1709
        }
×
1710

1711
        // With the tree constructed, we can make the pkscript which is the
1712
        // taproot output key itself.
1713
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
3✔
1714
        outputKey := txscript.ComputeTaprootOutputKey(
3✔
1715
                revokeKey, tapScriptRoot[:],
3✔
1716
        )
3✔
1717

3✔
1718
        return &SecondLevelScriptTree{
3✔
1719
                ScriptTree: ScriptTree{
3✔
1720
                        TaprootKey:    outputKey,
3✔
1721
                        TapscriptTree: tapScriptTree,
3✔
1722
                        TapscriptRoot: tapScriptRoot[:],
3✔
1723
                        InternalKey:   revokeKey,
3✔
1724
                },
3✔
1725
                SuccessTapLeaf: tapScriptTree.LeafMerkleProofs[0].TapLeaf,
3✔
1726
                AuxLeaf:        auxLeaf,
3✔
1727
        }, nil
3✔
1728
}
1729

1730
// WitnessScriptToSign returns the witness script that we'll use when signing
1731
// for the remote party, and also verifying signatures on our transactions. As
1732
// an example, when we create an outgoing HTLC for the remote party, we want to
1733
// sign their success path.
1734
func (s *SecondLevelScriptTree) WitnessScriptToSign() []byte {
×
1735
        return s.SuccessTapLeaf.Script
×
1736
}
×
1737

1738
// WitnessScriptForPath returns the witness script for the given spending path.
1739
// An error is returned if the path is unknown.
1740
func (s *SecondLevelScriptTree) WitnessScriptForPath(
1741
        path ScriptPath) ([]byte, error) {
3✔
1742

3✔
1743
        switch path {
3✔
1744
        case ScriptPathDelay:
×
1745
                fallthrough
×
1746
        case ScriptPathSuccess:
3✔
1747
                return s.SuccessTapLeaf.Script, nil
3✔
1748

1749
        default:
×
1750
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1751
        }
1752
}
1753

1754
// CtrlBlockForPath returns the control block for the given spending path. For
1755
// script types that don't have a control block, nil is returned.
1756
func (s *SecondLevelScriptTree) CtrlBlockForPath(
1757
        path ScriptPath) (*txscript.ControlBlock, error) {
3✔
1758

3✔
1759
        switch path {
3✔
1760
        case ScriptPathDelay:
×
1761
                fallthrough
×
1762
        case ScriptPathSuccess:
3✔
1763
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
1764
                        s.SuccessTapLeaf.Script, s.InternalKey,
3✔
1765
                        s.TapscriptTree,
3✔
1766
                )), nil
3✔
1767

1768
        default:
×
1769
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1770
        }
1771
}
1772

1773
// Tree returns the underlying ScriptTree of the SecondLevelScriptTree.
1774
func (s *SecondLevelScriptTree) Tree() ScriptTree {
×
1775
        return s.ScriptTree
×
1776
}
×
1777

1778
// A compile time check to ensure SecondLevelScriptTree implements the
1779
// TapscriptDescriptor interface.
1780
var _ TapscriptDescriptor = (*SecondLevelScriptTree)(nil)
1781

1782
// TaprootHtlcSpendRevoke spends a second-level HTLC output via the revocation
1783
// path. This uses the top level keyspend path to redeem the contested output.
1784
//
1785
// The passed SignDescriptor MUST have the proper witness script and also the
1786
// proper top-level tweak derived from the tapscript tree for the second level
1787
// output.
1788
func TaprootHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1789
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1790

×
UNCOV
1791
        // We don't need any spacial modifications to the transaction as this
×
UNCOV
1792
        // is just sweeping a revoked HTLC output. So we'll generate a regular
×
UNCOV
1793
        // schnorr signature.
×
UNCOV
1794
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
×
UNCOV
1795
        if err != nil {
×
1796
                return nil, err
×
1797
        }
×
1798

1799
        // The witness stack in this case is pretty simple: we only need to
1800
        // specify the signature generated.
UNCOV
1801
        witnessStack := make(wire.TxWitness, 1)
×
UNCOV
1802
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
×
UNCOV
1803

×
UNCOV
1804
        return witnessStack, nil
×
1805
}
1806

1807
// TaprootHtlcSpendSuccess spends a second-level HTLC output via the redemption
1808
// path. This should be used to sweep funds after the pre-image is known.
1809
//
1810
// NOTE: The caller MUST set the txn version, sequence number, and sign
1811
// descriptor's sig hash cache before invocation.
1812
func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
1813
        sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1814
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
1815

3✔
1816
        // First, we'll generate the sweep signature based on the populated
3✔
1817
        // sign desc. This should give us a valid schnorr signature for the
3✔
1818
        // sole script path leaf.
3✔
1819
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1820
        if err != nil {
3✔
1821
                return nil, err
×
1822
        }
×
1823

1824
        var ctrlBlock []byte
3✔
1825
        if signDesc.ControlBlock == nil {
3✔
UNCOV
1826
                // Now that we have the sweep signature, we'll construct the
×
UNCOV
1827
                // control block needed to spend the script path.
×
UNCOV
1828
                redeemControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
1829
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
1830
                )
×
UNCOV
1831

×
UNCOV
1832
                ctrlBlock, err = redeemControlBlock.ToBytes()
×
UNCOV
1833
                if err != nil {
×
1834
                        return nil, err
×
1835
                }
×
1836
        } else {
3✔
1837
                ctrlBlock = signDesc.ControlBlock
3✔
1838
        }
3✔
1839

1840
        // Now that we have the redeem control block, we can construct the
1841
        // final witness needed to spend the script:
1842
        //
1843
        //  <success sig> <success script> <control_block>
1844
        witnessStack := make(wire.TxWitness, 3)
3✔
1845
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
1846
        witnessStack[1] = signDesc.WitnessScript
3✔
1847
        witnessStack[2] = ctrlBlock
3✔
1848

3✔
1849
        return witnessStack, nil
3✔
1850
}
1851

1852
// LeaseSecondLevelHtlcScript is the uniform script that's used as the output
1853
// for the second-level HTLC transactions. The second level transaction acts as
1854
// a sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1855
// spent in a particular way, and to a particular output.
1856
//
1857
// Possible Input Scripts:
1858
//
1859
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1860
//     state:
1861
//     <revoke sig> 1
1862
//
1863
//   - To claim an HTLC output, either with a pre-image or due to a timeout:
1864
//     <delay sig> 0
1865
//
1866
// Output Script:
1867
//
1868
//         OP_IF
1869
//                <revoke key>
1870
//         OP_ELSE
1871
//                <lease maturity in blocks>
1872
//                OP_CHECKLOCKTIMEVERIFY
1873
//                OP_DROP
1874
//                <delay in blocks>
1875
//                OP_CHECKSEQUENCEVERIFY
1876
//                OP_DROP
1877
//                <delay key>
1878
//         OP_ENDIF
1879
//         OP_CHECKSIG.
1880
func LeaseSecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1881
        csvDelay, cltvExpiry uint32) ([]byte, error) {
3✔
1882

3✔
1883
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
1884
                ToLocalScriptSize + LeaseWitnessScriptSizeOverhead,
3✔
1885
        ))
3✔
1886

3✔
1887
        // If this is the revocation clause for this script is to be executed,
3✔
1888
        // the spender will push a 1, forcing us to hit the true clause of this
3✔
1889
        // if statement.
3✔
1890
        builder.AddOp(txscript.OP_IF)
3✔
1891

3✔
1892
        // If this this is the revocation case, then we'll push the revocation
3✔
1893
        // public key on the stack.
3✔
1894
        builder.AddData(revocationKey.SerializeCompressed())
3✔
1895

3✔
1896
        // Otherwise, this is either the sender or receiver of the HTLC
3✔
1897
        // attempting to claim the HTLC output.
3✔
1898
        builder.AddOp(txscript.OP_ELSE)
3✔
1899

3✔
1900
        // The channel initiator always has the additional channel lease
3✔
1901
        // expiration constraint for outputs that pay to them which must be
3✔
1902
        // satisfied.
3✔
1903
        builder.AddInt64(int64(cltvExpiry))
3✔
1904
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
3✔
1905
        builder.AddOp(txscript.OP_DROP)
3✔
1906

3✔
1907
        // In order to give the other party time to execute the revocation
3✔
1908
        // clause above, we require a relative timeout to pass before the
3✔
1909
        // output can be spent.
3✔
1910
        builder.AddInt64(int64(csvDelay))
3✔
1911
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
1912
        builder.AddOp(txscript.OP_DROP)
3✔
1913

3✔
1914
        // If the relative timelock passes, then we'll add the delay key to the
3✔
1915
        // stack to ensure that we properly authenticate the spending party.
3✔
1916
        builder.AddData(delayKey.SerializeCompressed())
3✔
1917

3✔
1918
        // Close out the if statement.
3✔
1919
        builder.AddOp(txscript.OP_ENDIF)
3✔
1920

3✔
1921
        // In either case, we'll ensure that only either the party possessing
3✔
1922
        // the revocation private key, or the delay private key is able to
3✔
1923
        // spend this output.
3✔
1924
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
1925

3✔
1926
        return builder.Script()
3✔
1927
}
3✔
1928

1929
// HtlcSpendSuccess spends a second-level HTLC output. This function is to be
1930
// used by the sender of an HTLC to claim the output after a relative timeout
1931
// or the receiver of the HTLC to claim on-chain with the pre-image.
1932
func HtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
UNCOV
1933
        sweepTx *wire.MsgTx, csvDelay uint32) (wire.TxWitness, error) {
×
UNCOV
1934

×
UNCOV
1935
        // We're required to wait a relative period of time before we can sweep
×
UNCOV
1936
        // the output in order to allow the other party to contest our claim of
×
UNCOV
1937
        // validity to this version of the commitment transaction.
×
UNCOV
1938
        sweepTx.TxIn[0].Sequence = LockTimeToSequence(false, csvDelay)
×
UNCOV
1939

×
UNCOV
1940
        // Finally, OP_CSV requires that the version of the transaction
×
UNCOV
1941
        // spending a pkscript with OP_CSV within it *must* be >= 2.
×
UNCOV
1942
        sweepTx.Version = 2
×
UNCOV
1943

×
UNCOV
1944
        // As we mutated the transaction, we'll re-calculate the sighashes for
×
UNCOV
1945
        // this instance.
×
UNCOV
1946
        signDesc.SigHashes = NewTxSigHashesV0Only(sweepTx)
×
UNCOV
1947

×
UNCOV
1948
        // With the proper sequence and version set, we'll now sign the timeout
×
UNCOV
1949
        // transaction using the passed signed descriptor. In order to generate
×
UNCOV
1950
        // a valid signature, then signDesc should be using the base delay
×
UNCOV
1951
        // public key, and the proper single tweak bytes.
×
UNCOV
1952
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
1953
        if err != nil {
×
1954
                return nil, err
×
1955
        }
×
1956

1957
        // We set a zero as the first element the witness stack (ignoring the
1958
        // witness script), in order to force execution to the second portion
1959
        // of the if clause.
UNCOV
1960
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1961
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1962
        witnessStack[1] = nil
×
UNCOV
1963
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1964

×
UNCOV
1965
        return witnessStack, nil
×
1966
}
1967

1968
// HtlcSpendRevoke spends a second-level HTLC output. This function is to be
1969
// used by the sender or receiver of an HTLC to claim the HTLC after a revoked
1970
// commitment transaction was broadcast.
1971
func HtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1972
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1973

×
UNCOV
1974
        // We don't need any spacial modifications to the transaction as this
×
UNCOV
1975
        // is just sweeping a revoked HTLC output. So we'll generate a regular
×
UNCOV
1976
        // witness signature.
×
UNCOV
1977
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
×
UNCOV
1978
        if err != nil {
×
1979
                return nil, err
×
1980
        }
×
1981

1982
        // We set a one as the first element the witness stack (ignoring the
1983
        // witness script), in order to force execution to the revocation
1984
        // clause in the second level HTLC script.
UNCOV
1985
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1986
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1987
        witnessStack[1] = []byte{1}
×
UNCOV
1988
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1989

×
UNCOV
1990
        return witnessStack, nil
×
1991
}
1992

1993
// HtlcSecondLevelSpend exposes the public witness generation function for
1994
// spending an HTLC success transaction, either due to an expiring time lock or
1995
// having had the payment preimage. This method is able to spend any
1996
// second-level HTLC transaction, assuming the caller sets the locktime or
1997
// seqno properly.
1998
//
1999
// NOTE: The caller MUST set the txn version, sequence number, and sign
2000
// descriptor's sig hash cache before invocation.
2001
func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor,
2002
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
2003

3✔
2004
        // With the proper sequence and version set, we'll now sign the timeout
3✔
2005
        // transaction using the passed signed descriptor. In order to generate
3✔
2006
        // a valid signature, then signDesc should be using the base delay
3✔
2007
        // public key, and the proper single tweak bytes.
3✔
2008
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2009
        if err != nil {
3✔
2010
                return nil, err
×
2011
        }
×
2012

2013
        // We set a zero as the first element the witness stack (ignoring the
2014
        // witness script), in order to force execution to the second portion
2015
        // of the if clause.
2016
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
2017
        witnessStack[0] = append(sweepSig.Serialize(), byte(txscript.SigHashAll))
3✔
2018
        witnessStack[1] = nil
3✔
2019
        witnessStack[2] = signDesc.WitnessScript
3✔
2020

3✔
2021
        return witnessStack, nil
3✔
2022
}
2023

2024
// LockTimeToSequence converts the passed relative locktime to a sequence
2025
// number in accordance to BIP-68.
2026
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
2027
//   - (Compatibility)
UNCOV
2028
func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
×
UNCOV
2029
        if !isSeconds {
×
UNCOV
2030
                // The locktime is to be expressed in confirmations.
×
UNCOV
2031
                return locktime
×
UNCOV
2032
        }
×
2033

2034
        // Set the 22nd bit which indicates the lock time is in seconds, then
2035
        // shift the locktime over by 9 since the time granularity is in
2036
        // 512-second intervals (2^9). This results in a max lock-time of
2037
        // 33,554,431 seconds, or 1.06 years.
2038
        return SequenceLockTimeSeconds | (locktime >> 9)
×
2039
}
2040

2041
// CommitScriptToSelf constructs the public key script for the output on the
2042
// commitment transaction paying to the "owner" of said commitment transaction.
2043
// If the other party learns of the preimage to the revocation hash, then they
2044
// can claim all the settled funds in the channel, plus the unsettled funds.
2045
//
2046
// Possible Input Scripts:
2047
//
2048
//        REVOKE:     <sig> 1
2049
//        SENDRSWEEP: <sig> <emptyvector>
2050
//
2051
// Output Script:
2052
//
2053
//        OP_IF
2054
//            <revokeKey>
2055
//        OP_ELSE
2056
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
2057
//            <selfKey>
2058
//        OP_ENDIF
2059
//        OP_CHECKSIG
2060
func CommitScriptToSelf(csvTimeout uint32, selfKey, revokeKey *btcec.PublicKey) ([]byte, error) {
3✔
2061
        // This script is spendable under two conditions: either the
3✔
2062
        // 'csvTimeout' has passed and we can redeem our funds, or they can
3✔
2063
        // produce a valid signature with the revocation public key. The
3✔
2064
        // revocation public key will *only* be known to the other party if we
3✔
2065
        // have divulged the revocation hash, allowing them to homomorphically
3✔
2066
        // derive the proper private key which corresponds to the revoke public
3✔
2067
        // key.
3✔
2068
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
2069
                ToLocalScriptSize,
3✔
2070
        ))
3✔
2071

3✔
2072
        builder.AddOp(txscript.OP_IF)
3✔
2073

3✔
2074
        // If a valid signature using the revocation key is presented, then
3✔
2075
        // allow an immediate spend provided the proper signature.
3✔
2076
        builder.AddData(revokeKey.SerializeCompressed())
3✔
2077

3✔
2078
        builder.AddOp(txscript.OP_ELSE)
3✔
2079

3✔
2080
        // Otherwise, we can re-claim our funds after a CSV delay of
3✔
2081
        // 'csvTimeout' timeout blocks, and a valid signature.
3✔
2082
        builder.AddInt64(int64(csvTimeout))
3✔
2083
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2084
        builder.AddOp(txscript.OP_DROP)
3✔
2085
        builder.AddData(selfKey.SerializeCompressed())
3✔
2086

3✔
2087
        builder.AddOp(txscript.OP_ENDIF)
3✔
2088

3✔
2089
        // Finally, we'll validate the signature against the public key that's
3✔
2090
        // left on the top of the stack.
3✔
2091
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2092

3✔
2093
        return builder.Script()
3✔
2094
}
3✔
2095

2096
// CommitScriptTree holds the taproot output key (in this case the revocation
2097
// key, or a NUMs point for the remote output) along with the tapscript leaf
2098
// that can spend the output after a delay.
2099
type CommitScriptTree struct {
2100
        ScriptTree
2101

2102
        // SettleLeaf is the leaf used to settle the output after the delay.
2103
        SettleLeaf txscript.TapLeaf
2104

2105
        // RevocationLeaf is the leaf used to spend the output with the
2106
        // revocation key signature.
2107
        RevocationLeaf txscript.TapLeaf
2108

2109
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
2110
        // commitment script tree with new spend paths, or just as extra
2111
        // commitment space. When present, this leaf will always be in the
2112
        // left-most or right-most area of the tapscript tree.
2113
        AuxLeaf AuxTapLeaf
2114
}
2115

2116
// A compile time check to ensure CommitScriptTree implements the
2117
// TapscriptDescriptor interface.
2118
var _ TapscriptDescriptor = (*CommitScriptTree)(nil)
2119

2120
// WitnessScriptToSign returns the witness script that we'll use when signing
2121
// for the remote party, and also verifying signatures on our transactions. As
2122
// an example, when we create an outgoing HTLC for the remote party, we want to
2123
// sign their success path.
2124
func (c *CommitScriptTree) WitnessScriptToSign() []byte {
×
2125
        // TODO(roasbeef): abstraction leak here? always dependent
×
2126
        return nil
×
2127
}
×
2128

2129
// WitnessScriptForPath returns the witness script for the given spending path.
2130
// An error is returned if the path is unknown.
2131
func (c *CommitScriptTree) WitnessScriptForPath(
2132
        path ScriptPath) ([]byte, error) {
3✔
2133

3✔
2134
        switch path {
3✔
2135
        // For the commitment output, the delay and success path are the same,
2136
        // so we'll fall through here to success.
2137
        case ScriptPathDelay:
3✔
2138
                fallthrough
3✔
2139
        case ScriptPathSuccess:
3✔
2140
                return c.SettleLeaf.Script, nil
3✔
2141
        case ScriptPathRevocation:
3✔
2142
                return c.RevocationLeaf.Script, nil
3✔
2143
        default:
×
2144
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2145
        }
2146
}
2147

2148
// CtrlBlockForPath returns the control block for the given spending path. For
2149
// script types that don't have a control block, nil is returned.
2150
func (c *CommitScriptTree) CtrlBlockForPath(
2151
        path ScriptPath) (*txscript.ControlBlock, error) {
3✔
2152

3✔
2153
        switch path {
3✔
2154
        case ScriptPathDelay:
3✔
2155
                fallthrough
3✔
2156
        case ScriptPathSuccess:
3✔
2157
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
2158
                        c.SettleLeaf.Script, c.InternalKey,
3✔
2159
                        c.TapscriptTree,
3✔
2160
                )), nil
3✔
2161
        case ScriptPathRevocation:
3✔
2162
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
2163
                        c.RevocationLeaf.Script, c.InternalKey,
3✔
2164
                        c.TapscriptTree,
3✔
2165
                )), nil
3✔
2166
        default:
×
2167
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2168
        }
2169
}
2170

2171
// Tree returns the underlying ScriptTree of the CommitScriptTree.
2172
func (c *CommitScriptTree) Tree() ScriptTree {
×
2173
        return c.ScriptTree
×
2174
}
×
2175

2176
// NewLocalCommitScriptTree returns a new CommitScript tree that can be used to
2177
// create and spend the commitment output for the local party.
2178
func NewLocalCommitScriptTree(csvTimeout uint32, selfKey,
2179
        revokeKey *btcec.PublicKey, auxLeaf AuxTapLeaf) (*CommitScriptTree,
2180
        error) {
3✔
2181

3✔
2182
        // First, we'll need to construct the tapLeaf that'll be our delay CSV
3✔
2183
        // clause.
3✔
2184
        delayScript, err := TaprootLocalCommitDelayScript(csvTimeout, selfKey)
3✔
2185
        if err != nil {
3✔
2186
                return nil, err
×
2187
        }
×
2188

2189
        // Next, we'll need to construct the revocation path, which is just a
2190
        // simple checksig script.
2191
        revokeScript, err := TaprootLocalCommitRevokeScript(selfKey, revokeKey)
3✔
2192
        if err != nil {
3✔
2193
                return nil, err
×
2194
        }
×
2195

2196
        // With both scripts computed, we'll now create a tapscript tree with
2197
        // the two leaves, and then obtain a root from that.
2198
        delayTapLeaf := txscript.NewBaseTapLeaf(delayScript)
3✔
2199
        revokeTapLeaf := txscript.NewBaseTapLeaf(revokeScript)
3✔
2200

3✔
2201
        tapLeaves := []txscript.TapLeaf{delayTapLeaf, revokeTapLeaf}
3✔
2202
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
3✔
UNCOV
2203
                tapLeaves = append(tapLeaves, l)
×
UNCOV
2204
        })
×
2205

2206
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
3✔
2207
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
3✔
2208

3✔
2209
        // Now that we have our root, we can arrive at the final output script
3✔
2210
        // by tweaking the internal key with this root.
3✔
2211
        toLocalOutputKey := txscript.ComputeTaprootOutputKey(
3✔
2212
                &TaprootNUMSKey, tapScriptRoot[:],
3✔
2213
        )
3✔
2214

3✔
2215
        return &CommitScriptTree{
3✔
2216
                ScriptTree: ScriptTree{
3✔
2217
                        TaprootKey:    toLocalOutputKey,
3✔
2218
                        TapscriptTree: tapScriptTree,
3✔
2219
                        TapscriptRoot: tapScriptRoot[:],
3✔
2220
                        InternalKey:   &TaprootNUMSKey,
3✔
2221
                },
3✔
2222
                SettleLeaf:     delayTapLeaf,
3✔
2223
                RevocationLeaf: revokeTapLeaf,
3✔
2224
                AuxLeaf:        auxLeaf,
3✔
2225
        }, nil
3✔
2226
}
2227

2228
// TaprootLocalCommitDelayScript builds the tap leaf with the CSV delay script
2229
// for the to-local output.
2230
func TaprootLocalCommitDelayScript(csvTimeout uint32,
2231
        selfKey *btcec.PublicKey) ([]byte, error) {
3✔
2232

3✔
2233
        builder := txscript.NewScriptBuilder()
3✔
2234
        builder.AddData(schnorr.SerializePubKey(selfKey))
3✔
2235
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2236
        builder.AddInt64(int64(csvTimeout))
3✔
2237
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2238
        builder.AddOp(txscript.OP_DROP)
3✔
2239

3✔
2240
        return builder.Script()
3✔
2241
}
3✔
2242

2243
// TaprootLocalCommitRevokeScript builds the tap leaf with the revocation path
2244
// for the to-local output.
2245
func TaprootLocalCommitRevokeScript(selfKey, revokeKey *btcec.PublicKey) (
2246
        []byte, error) {
3✔
2247

3✔
2248
        builder := txscript.NewScriptBuilder()
3✔
2249
        builder.AddData(schnorr.SerializePubKey(selfKey))
3✔
2250
        builder.AddOp(txscript.OP_DROP)
3✔
2251
        builder.AddData(schnorr.SerializePubKey(revokeKey))
3✔
2252
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2253

3✔
2254
        return builder.Script()
3✔
2255
}
3✔
2256

2257
// TaprootCommitScriptToSelf creates the taproot witness program that commits
2258
// to the revocation (script path) and delay path (script path) in a single
2259
// taproot output key. Both the delay script and the revocation script are part
2260
// of the tapscript tree to ensure that the internal key (the local delay key)
2261
// is always revealed.  This ensures that a 3rd party can always sweep the set
2262
// of anchor outputs.
2263
//
2264
// For the delay path we have the following tapscript leaf script:
2265
//
2266
//        <local_delayedpubkey> OP_CHECKSIG
2267
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
2268
//
2269
// This can then be spent with just:
2270
//
2271
//        <local_delayedsig> <to_delay_script> <delay_control_block>
2272
//
2273
// Where the to_delay_script is listed above, and the delay_control_block
2274
// computed as:
2275
//
2276
//        delay_control_block = (output_key_y_parity | 0xc0) || taproot_nums_key
2277
//
2278
// The revocation path is simply:
2279
//
2280
//        <local_delayedpubkey> OP_DROP
2281
//        <revocationkey> OP_CHECKSIG
2282
//
2283
// The revocation path can be spent with a control block similar to the above
2284
// (but contains the hash of the other script), and with the following witness:
2285
//
2286
//        <revocation_sig>
2287
//
2288
// We use a noop data push to ensure that the local public key is also revealed
2289
// on chain, which enables the anchor output to be swept.
2290
func TaprootCommitScriptToSelf(csvTimeout uint32,
2291
        selfKey, revokeKey *btcec.PublicKey) (*btcec.PublicKey, error) {
×
2292

×
2293
        commitScriptTree, err := NewLocalCommitScriptTree(
×
2294
                csvTimeout, selfKey, revokeKey, NoneTapLeaf(),
×
2295
        )
×
2296
        if err != nil {
×
2297
                return nil, err
×
2298
        }
×
2299

2300
        return commitScriptTree.TaprootKey, nil
×
2301
}
2302

2303
// MakeTaprootCtrlBlock takes a leaf script, the internal key (usually the
2304
// revoke key), and a script tree and creates a valid control block for a spend
2305
// of the leaf.
2306
func MakeTaprootCtrlBlock(leafScript []byte, internalKey *btcec.PublicKey,
2307
        scriptTree *txscript.IndexedTapScriptTree) txscript.ControlBlock {
3✔
2308

3✔
2309
        tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
3✔
2310
        scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
3✔
2311
        settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
3✔
2312

3✔
2313
        return settleMerkleProof.ToControlBlock(internalKey)
3✔
2314
}
3✔
2315

2316
// TaprootCommitSpendSuccess constructs a valid witness allowing a node to
2317
// sweep the settled taproot output after the delay has passed for a force
2318
// close.
2319
func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
2320
        sweepTx *wire.MsgTx,
2321
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
2322

3✔
2323
        // First, we'll need to construct a valid control block to execute the
3✔
2324
        // leaf script for sweep settlement.
3✔
2325
        //
3✔
2326
        // TODO(roasbeef); make into closure instead? only need reovke key and
3✔
2327
        // scriptTree to make the ctrl block -- then default version that would
3✔
2328
        // take froms ign desc?
3✔
2329
        var ctrlBlockBytes []byte
3✔
2330
        if signDesc.ControlBlock == nil {
3✔
UNCOV
2331
                settleControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2332
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2333
                )
×
UNCOV
2334
                ctrlBytes, err := settleControlBlock.ToBytes()
×
UNCOV
2335
                if err != nil {
×
2336
                        return nil, err
×
2337
                }
×
2338

UNCOV
2339
                ctrlBlockBytes = ctrlBytes
×
2340
        } else {
3✔
2341
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2342
        }
3✔
2343

2344
        // With the control block created, we'll now generate the signature we
2345
        // need to authorize the spend.
2346
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2347
        if err != nil {
3✔
2348
                return nil, err
×
2349
        }
×
2350

2351
        // The final witness stack will be:
2352
        //
2353
        //  <sweep sig> <sweep script> <control block>
2354
        witnessStack := make(wire.TxWitness, 3)
3✔
2355
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
2356
        witnessStack[1] = signDesc.WitnessScript
3✔
2357
        witnessStack[2] = ctrlBlockBytes
3✔
2358

3✔
2359
        return witnessStack, nil
3✔
2360
}
2361

2362
// TaprootCommitSpendRevoke constructs a valid witness allowing a node to sweep
2363
// the revoked taproot output of a malicious peer.
2364
func TaprootCommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2365
        revokeTx *wire.MsgTx,
2366
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
2367

3✔
2368
        // First, we'll need to construct a valid control block to execute the
3✔
2369
        // leaf script for revocation path.
3✔
2370
        var ctrlBlockBytes []byte
3✔
2371
        if signDesc.ControlBlock == nil {
3✔
UNCOV
2372
                revokeCtrlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2373
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2374
                )
×
UNCOV
2375
                revokeBytes, err := revokeCtrlBlock.ToBytes()
×
UNCOV
2376
                if err != nil {
×
2377
                        return nil, err
×
2378
                }
×
2379

UNCOV
2380
                ctrlBlockBytes = revokeBytes
×
2381
        } else {
3✔
2382
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2383
        }
3✔
2384

2385
        // With the control block created, we'll now generate the signature we
2386
        // need to authorize the spend.
2387
        revokeSig, err := signer.SignOutputRaw(revokeTx, signDesc)
3✔
2388
        if err != nil {
3✔
2389
                return nil, err
×
2390
        }
×
2391

2392
        // The final witness stack will be:
2393
        //
2394
        //  <revoke sig sig> <revoke script> <control block>
2395
        witnessStack := make(wire.TxWitness, 3)
3✔
2396
        witnessStack[0] = maybeAppendSighash(revokeSig, signDesc.HashType)
3✔
2397
        witnessStack[1] = signDesc.WitnessScript
3✔
2398
        witnessStack[2] = ctrlBlockBytes
3✔
2399

3✔
2400
        return witnessStack, nil
3✔
2401
}
2402

2403
// LeaseCommitScriptToSelf constructs the public key script for the output on the
2404
// commitment transaction paying to the "owner" of said commitment transaction.
2405
// If the other party learns of the preimage to the revocation hash, then they
2406
// can claim all the settled funds in the channel, plus the unsettled funds.
2407
//
2408
// Possible Input Scripts:
2409
//
2410
//        REVOKE:     <sig> 1
2411
//        SENDRSWEEP: <sig> <emptyvector>
2412
//
2413
// Output Script:
2414
//
2415
//        OP_IF
2416
//            <revokeKey>
2417
//        OP_ELSE
2418
//            <absoluteLeaseExpiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
2419
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
2420
//            <selfKey>
2421
//        OP_ENDIF
2422
//        OP_CHECKSIG
2423
func LeaseCommitScriptToSelf(selfKey, revokeKey *btcec.PublicKey,
2424
        csvTimeout, leaseExpiry uint32) ([]byte, error) {
3✔
2425

3✔
2426
        // This script is spendable under two conditions: either the
3✔
2427
        // 'csvTimeout' has passed and we can redeem our funds, or they can
3✔
2428
        // produce a valid signature with the revocation public key. The
3✔
2429
        // revocation public key will *only* be known to the other party if we
3✔
2430
        // have divulged the revocation hash, allowing them to homomorphically
3✔
2431
        // derive the proper private key which corresponds to the revoke public
3✔
2432
        // key.
3✔
2433
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
2434
                ToLocalScriptSize + LeaseWitnessScriptSizeOverhead,
3✔
2435
        ))
3✔
2436

3✔
2437
        builder.AddOp(txscript.OP_IF)
3✔
2438

3✔
2439
        // If a valid signature using the revocation key is presented, then
3✔
2440
        // allow an immediate spend provided the proper signature.
3✔
2441
        builder.AddData(revokeKey.SerializeCompressed())
3✔
2442

3✔
2443
        builder.AddOp(txscript.OP_ELSE)
3✔
2444

3✔
2445
        // Otherwise, we can re-claim our funds after once the CLTV lease
3✔
2446
        // maturity has been met, along with the CSV delay of 'csvTimeout'
3✔
2447
        // timeout blocks, and a valid signature.
3✔
2448
        builder.AddInt64(int64(leaseExpiry))
3✔
2449
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
3✔
2450
        builder.AddOp(txscript.OP_DROP)
3✔
2451

3✔
2452
        builder.AddInt64(int64(csvTimeout))
3✔
2453
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2454
        builder.AddOp(txscript.OP_DROP)
3✔
2455

3✔
2456
        builder.AddData(selfKey.SerializeCompressed())
3✔
2457

3✔
2458
        builder.AddOp(txscript.OP_ENDIF)
3✔
2459

3✔
2460
        // Finally, we'll validate the signature against the public key that's
3✔
2461
        // left on the top of the stack.
3✔
2462
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2463

3✔
2464
        return builder.Script()
3✔
2465
}
3✔
2466

2467
// CommitSpendTimeout constructs a valid witness allowing the owner of a
2468
// particular commitment transaction to spend the output returning settled
2469
// funds back to themselves after a relative block timeout.  In order to
2470
// properly spend the transaction, the target input's sequence number should be
2471
// set accordingly based off of the target relative block timeout within the
2472
// redeem script.  Additionally, OP_CSV requires that the version of the
2473
// transaction spending a pkscript with OP_CSV within it *must* be >= 2.
2474
func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
2475
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
2476

3✔
2477
        // Ensure the transaction version supports the validation of sequence
3✔
2478
        // locks and CSV semantics.
3✔
2479
        if sweepTx.Version < 2 {
3✔
2480
                return nil, fmt.Errorf("version of passed transaction MUST "+
×
2481
                        "be >= 2, not %v", sweepTx.Version)
×
2482
        }
×
2483

2484
        // With the sequence number in place, we're now able to properly sign
2485
        // off on the sweep transaction.
2486
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2487
        if err != nil {
3✔
2488
                return nil, err
×
2489
        }
×
2490

2491
        // Place an empty byte as the first item in the evaluated witness stack
2492
        // to force script execution to the timeout spend clause. We need to
2493
        // place an empty byte in order to ensure our script is still valid
2494
        // from the PoV of nodes that are enforcing minimal OP_IF/OP_NOTIF.
2495
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
2496
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
2497
        witnessStack[1] = nil
3✔
2498
        witnessStack[2] = signDesc.WitnessScript
3✔
2499

3✔
2500
        return witnessStack, nil
3✔
2501
}
2502

2503
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
2504
// settled output of a malicious counterparty who broadcasts a revoked
2505
// commitment transaction.
2506
//
2507
// NOTE: The passed SignDescriptor should include the raw (untweaked)
2508
// revocation base public key of the receiver and also the proper double tweak
2509
// value based on the commitment secret of the revoked commitment.
2510
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2511
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
2512

3✔
2513
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2514
        if err != nil {
3✔
2515
                return nil, err
×
2516
        }
×
2517

2518
        // Place a 1 as the first item in the evaluated witness stack to
2519
        // force script execution to the revocation clause.
2520
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
2521
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
2522
        witnessStack[1] = []byte{1}
3✔
2523
        witnessStack[2] = signDesc.WitnessScript
3✔
2524

3✔
2525
        return witnessStack, nil
3✔
2526
}
2527

2528
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
2529
// settled no-delay output on the counterparty's commitment transaction. If the
2530
// tweakless field is true, then we'll omit the set where we tweak the pubkey
2531
// with a random set of bytes, and use it directly in the witness stack.
2532
//
2533
// NOTE: The passed SignDescriptor should include the raw (untweaked) public
2534
// key of the receiver and also the proper single tweak value based on the
2535
// current commitment point.
2536
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
2537
        sweepTx *wire.MsgTx, tweakless bool) (wire.TxWitness, error) {
3✔
2538

3✔
2539
        if signDesc.KeyDesc.PubKey == nil {
3✔
2540
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2541
                        "KeyDesc pubkey")
×
2542
        }
×
2543

2544
        // This is just a regular p2wkh spend which looks something like:
2545
        //  * witness: <sig> <pubkey>
2546
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2547
        if err != nil {
3✔
2548
                return nil, err
×
2549
        }
×
2550

2551
        // Finally, we'll manually craft the witness. The witness here is the
2552
        // exact same as a regular p2wkh witness, depending on the value of the
2553
        // tweakless bool.
2554
        witness := make([][]byte, 2)
3✔
2555
        witness[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
2556

3✔
2557
        switch tweakless {
3✔
2558
        // If we're tweaking the key, then we use the tweaked public key as the
2559
        // last item in the witness stack which was originally used to created
2560
        // the pkScript we're spending.
2561
        case false:
3✔
2562
                witness[1] = TweakPubKeyWithTweak(
3✔
2563
                        signDesc.KeyDesc.PubKey, signDesc.SingleTweak,
3✔
2564
                ).SerializeCompressed()
3✔
2565

2566
        // Otherwise, we can just use the raw pubkey, since there's no random
2567
        // value to be combined.
2568
        case true:
3✔
2569
                witness[1] = signDesc.KeyDesc.PubKey.SerializeCompressed()
3✔
2570
        }
2571

2572
        return witness, nil
3✔
2573
}
2574

2575
// CommitScriptUnencumbered constructs the public key script on the commitment
2576
// transaction paying to the "other" party. The constructed output is a normal
2577
// p2wkh output spendable immediately, requiring no contestation period.
2578
func CommitScriptUnencumbered(key *btcec.PublicKey) ([]byte, error) {
3✔
2579
        // This script goes to the "other" party, and is spendable immediately.
3✔
2580
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
2581
                P2WPKHSize,
3✔
2582
        ))
3✔
2583
        builder.AddOp(txscript.OP_0)
3✔
2584
        builder.AddData(btcutil.Hash160(key.SerializeCompressed()))
3✔
2585

3✔
2586
        return builder.Script()
3✔
2587
}
3✔
2588

2589
// CommitScriptToRemoteConfirmed constructs the script for the output on the
2590
// commitment transaction paying to the remote party of said commitment
2591
// transaction. The money can only be spend after one confirmation.
2592
//
2593
// Possible Input Scripts:
2594
//
2595
//        SWEEP: <sig>
2596
//
2597
// Output Script:
2598
//
2599
//        <key> OP_CHECKSIGVERIFY
2600
//        1 OP_CHECKSEQUENCEVERIFY
2601
func CommitScriptToRemoteConfirmed(key *btcec.PublicKey) ([]byte, error) {
3✔
2602
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
2603
                ToRemoteConfirmedScriptSize,
3✔
2604
        ))
3✔
2605

3✔
2606
        // Only the given key can spend the output.
3✔
2607
        builder.AddData(key.SerializeCompressed())
3✔
2608
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
2609

3✔
2610
        // Check that the it has one confirmation.
3✔
2611
        builder.AddOp(txscript.OP_1)
3✔
2612
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2613

3✔
2614
        return builder.Script()
3✔
2615
}
3✔
2616

2617
// NewRemoteCommitScriptTree constructs a new script tree for the remote party
2618
// to sweep their funds after a hard coded 1 block delay.
2619
func NewRemoteCommitScriptTree(remoteKey *btcec.PublicKey,
2620
        auxLeaf AuxTapLeaf) (*CommitScriptTree, error) {
3✔
2621

3✔
2622
        // First, construct the remote party's tapscript they'll use to sweep
3✔
2623
        // their outputs.
3✔
2624
        builder := txscript.NewScriptBuilder()
3✔
2625
        builder.AddData(schnorr.SerializePubKey(remoteKey))
3✔
2626
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2627
        builder.AddOp(txscript.OP_1)
3✔
2628
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2629
        builder.AddOp(txscript.OP_DROP)
3✔
2630

3✔
2631
        remoteScript, err := builder.Script()
3✔
2632
        if err != nil {
3✔
2633
                return nil, err
×
2634
        }
×
2635

2636
        tapLeaf := txscript.NewBaseTapLeaf(remoteScript)
3✔
2637

3✔
2638
        tapLeaves := []txscript.TapLeaf{tapLeaf}
3✔
2639
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
3✔
UNCOV
2640
                tapLeaves = append(tapLeaves, l)
×
UNCOV
2641
        })
×
2642

2643
        // With this script constructed, we'll map that into a tapLeaf, then
2644
        // make a new tapscript root from that.
2645
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
3✔
2646
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
3✔
2647

3✔
2648
        // Now that we have our root, we can arrive at the final output script
3✔
2649
        // by tweaking the internal key with this root.
3✔
2650
        toRemoteOutputKey := txscript.ComputeTaprootOutputKey(
3✔
2651
                &TaprootNUMSKey, tapScriptRoot[:],
3✔
2652
        )
3✔
2653

3✔
2654
        return &CommitScriptTree{
3✔
2655
                ScriptTree: ScriptTree{
3✔
2656
                        TaprootKey:    toRemoteOutputKey,
3✔
2657
                        TapscriptTree: tapScriptTree,
3✔
2658
                        TapscriptRoot: tapScriptRoot[:],
3✔
2659
                        InternalKey:   &TaprootNUMSKey,
3✔
2660
                },
3✔
2661
                SettleLeaf: tapLeaf,
3✔
2662
                AuxLeaf:    auxLeaf,
3✔
2663
        }, nil
3✔
2664
}
2665

2666
// TaprootCommitScriptToRemote constructs a taproot witness program for the
2667
// output on the commitment transaction for the remote party. For the top level
2668
// key spend, we'll use a NUMs key to ensure that only the script path can be
2669
// taken. Using a set NUMs key here also means that recovery solutions can scan
2670
// the chain given knowledge of the public key for the remote party. We then
2671
// commit to a single tapscript leaf that holds the normal CSV 1 delay
2672
// script.
2673
//
2674
// Our single tapleaf will use the following script:
2675
//
2676
//        <remotepubkey> OP_CHECKSIG
2677
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
2678
func TaprootCommitScriptToRemote(remoteKey *btcec.PublicKey,
2679
        auxLeaf AuxTapLeaf) (*btcec.PublicKey, error) {
×
2680

×
2681
        commitScriptTree, err := NewRemoteCommitScriptTree(remoteKey, auxLeaf)
×
2682
        if err != nil {
×
2683
                return nil, err
×
2684
        }
×
2685

2686
        return commitScriptTree.TaprootKey, nil
×
2687
}
2688

2689
// TaprootCommitRemoteSpend allows the remote party to sweep their output into
2690
// their wallet after an enforced 1 block delay.
2691
func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
2692
        sweepTx *wire.MsgTx,
2693
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
3✔
2694

3✔
2695
        // First, we'll need to construct a valid control block to execute the
3✔
2696
        // leaf script for sweep settlement.
3✔
2697
        var ctrlBlockBytes []byte
3✔
2698
        if signDesc.ControlBlock == nil {
3✔
UNCOV
2699
                settleControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2700
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2701
                )
×
UNCOV
2702
                ctrlBytes, err := settleControlBlock.ToBytes()
×
UNCOV
2703
                if err != nil {
×
2704
                        return nil, err
×
2705
                }
×
2706

UNCOV
2707
                ctrlBlockBytes = ctrlBytes
×
2708
        } else {
3✔
2709
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2710
        }
3✔
2711

2712
        // With the control block created, we'll now generate the signature we
2713
        // need to authorize the spend.
2714
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2715
        if err != nil {
3✔
2716
                return nil, err
×
2717
        }
×
2718

2719
        // The final witness stack will be:
2720
        //
2721
        //  <sweep sig> <sweep script> <control block>
2722
        witnessStack := make(wire.TxWitness, 3)
3✔
2723
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
2724
        witnessStack[1] = signDesc.WitnessScript
3✔
2725
        witnessStack[2] = ctrlBlockBytes
3✔
2726

3✔
2727
        return witnessStack, nil
3✔
2728
}
2729

2730
// LeaseCommitScriptToRemoteConfirmed constructs the script for the output on
2731
// the commitment transaction paying to the remote party of said commitment
2732
// transaction. The money can only be spend after one confirmation.
2733
//
2734
// Possible Input Scripts:
2735
//
2736
//        SWEEP: <sig>
2737
//
2738
// Output Script:
2739
//
2740
//                <key> OP_CHECKSIGVERIFY
2741
//             <lease maturity in blocks> OP_CHECKLOCKTIMEVERIFY OP_DROP
2742
//                1 OP_CHECKSEQUENCEVERIFY
2743
func LeaseCommitScriptToRemoteConfirmed(key *btcec.PublicKey,
2744
        leaseExpiry uint32) ([]byte, error) {
3✔
2745

3✔
2746
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(45))
3✔
2747

3✔
2748
        // Only the given key can spend the output.
3✔
2749
        builder.AddData(key.SerializeCompressed())
3✔
2750
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
2751

3✔
2752
        // The channel initiator always has the additional channel lease
3✔
2753
        // expiration constraint for outputs that pay to them which must be
3✔
2754
        // satisfied.
3✔
2755
        builder.AddInt64(int64(leaseExpiry))
3✔
2756
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
3✔
2757
        builder.AddOp(txscript.OP_DROP)
3✔
2758

3✔
2759
        // Check that it has one confirmation.
3✔
2760
        builder.AddOp(txscript.OP_1)
3✔
2761
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2762

3✔
2763
        return builder.Script()
3✔
2764
}
3✔
2765

2766
// CommitSpendToRemoteConfirmed constructs a valid witness allowing a node to
2767
// spend their settled output on the counterparty's commitment transaction when
2768
// it has one confirmetion. This is used for the anchor channel type. The
2769
// spending key will always be non-tweaked for this output type.
2770
func CommitSpendToRemoteConfirmed(signer Signer, signDesc *SignDescriptor,
2771
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
2772

3✔
2773
        if signDesc.KeyDesc.PubKey == nil {
3✔
2774
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2775
                        "KeyDesc pubkey")
×
2776
        }
×
2777

2778
        // Similar to non delayed output, only a signature is needed.
2779
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2780
        if err != nil {
3✔
2781
                return nil, err
×
2782
        }
×
2783

2784
        // Finally, we'll manually craft the witness. The witness here is the
2785
        // signature and the redeem script.
2786
        witnessStack := make([][]byte, 2)
3✔
2787
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
2788
        witnessStack[1] = signDesc.WitnessScript
3✔
2789

3✔
2790
        return witnessStack, nil
3✔
2791
}
2792

2793
// CommitScriptAnchor constructs the script for the anchor output spendable by
2794
// the given key immediately, or by anyone after 16 confirmations.
2795
//
2796
// Possible Input Scripts:
2797
//
2798
//        By owner:                                <sig>
2799
//        By anyone (after 16 conf):        <emptyvector>
2800
//
2801
// Output Script:
2802
//
2803
//        <funding_pubkey> OP_CHECKSIG OP_IFDUP
2804
//        OP_NOTIF
2805
//          OP_16 OP_CSV
2806
//        OP_ENDIF
2807
func CommitScriptAnchor(key *btcec.PublicKey) ([]byte, error) {
3✔
2808
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
2809
                AnchorScriptSize,
3✔
2810
        ))
3✔
2811

3✔
2812
        // Spend immediately with key.
3✔
2813
        builder.AddData(key.SerializeCompressed())
3✔
2814
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2815

3✔
2816
        // Duplicate the value if true, since it will be consumed by the NOTIF.
3✔
2817
        builder.AddOp(txscript.OP_IFDUP)
3✔
2818

3✔
2819
        // Otherwise spendable by anyone after 16 confirmations.
3✔
2820
        builder.AddOp(txscript.OP_NOTIF)
3✔
2821
        builder.AddOp(txscript.OP_16)
3✔
2822
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2823
        builder.AddOp(txscript.OP_ENDIF)
3✔
2824

3✔
2825
        return builder.Script()
3✔
2826
}
3✔
2827

2828
// AnchorScriptTree holds all the contents needed to sweep a taproot anchor
2829
// output on chain.
2830
type AnchorScriptTree struct {
2831
        ScriptTree
2832

2833
        // SweepLeaf is the leaf used to settle the output after the delay.
2834
        SweepLeaf txscript.TapLeaf
2835
}
2836

2837
// NewAnchorScriptTree makes a new script tree for an anchor output with the
2838
// passed anchor key.
2839
func NewAnchorScriptTree(
2840
        anchorKey *btcec.PublicKey) (*AnchorScriptTree, error) {
3✔
2841

3✔
2842
        // The main script used is just a OP_16 CSV (anyone can sweep after 16
3✔
2843
        // blocks).
3✔
2844
        builder := txscript.NewScriptBuilder()
3✔
2845
        builder.AddOp(txscript.OP_16)
3✔
2846
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2847

3✔
2848
        anchorScript, err := builder.Script()
3✔
2849
        if err != nil {
3✔
2850
                return nil, err
×
2851
        }
×
2852

2853
        // With the script, we can make our sole leaf, then derive the root
2854
        // from that.
2855
        tapLeaf := txscript.NewBaseTapLeaf(anchorScript)
3✔
2856
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)
3✔
2857
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
3✔
2858

3✔
2859
        // Now that we have our root, we can arrive at the final output script
3✔
2860
        // by tweaking the internal key with this root.
3✔
2861
        anchorOutputKey := txscript.ComputeTaprootOutputKey(
3✔
2862
                anchorKey, tapScriptRoot[:],
3✔
2863
        )
3✔
2864

3✔
2865
        return &AnchorScriptTree{
3✔
2866
                ScriptTree: ScriptTree{
3✔
2867
                        TaprootKey:    anchorOutputKey,
3✔
2868
                        TapscriptTree: tapScriptTree,
3✔
2869
                        TapscriptRoot: tapScriptRoot[:],
3✔
2870
                        InternalKey:   anchorKey,
3✔
2871
                },
3✔
2872
                SweepLeaf: tapLeaf,
3✔
2873
        }, nil
3✔
2874
}
2875

2876
// WitnessScriptToSign returns the witness script that we'll use when signing
2877
// for the remote party, and also verifying signatures on our transactions. As
2878
// an example, when we create an outgoing HTLC for the remote party, we want to
2879
// sign their success path.
2880
func (a *AnchorScriptTree) WitnessScriptToSign() []byte {
×
2881
        return a.SweepLeaf.Script
×
2882
}
×
2883

2884
// WitnessScriptForPath returns the witness script for the given spending path.
2885
// An error is returned if the path is unknown.
2886
func (a *AnchorScriptTree) WitnessScriptForPath(
2887
        path ScriptPath) ([]byte, error) {
3✔
2888

3✔
2889
        switch path {
3✔
2890
        case ScriptPathDelay:
×
2891
                fallthrough
×
2892
        case ScriptPathSuccess:
3✔
2893
                return a.SweepLeaf.Script, nil
3✔
2894

2895
        default:
×
2896
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2897
        }
2898
}
2899

2900
// CtrlBlockForPath returns the control block for the given spending path. For
2901
// script types that don't have a control block, nil is returned.
2902
func (a *AnchorScriptTree) CtrlBlockForPath(
2903
        path ScriptPath) (*txscript.ControlBlock, error) {
×
2904

×
2905
        switch path {
×
2906
        case ScriptPathDelay:
×
2907
                fallthrough
×
2908
        case ScriptPathSuccess:
×
2909
                return lnutils.Ptr(MakeTaprootCtrlBlock(
×
2910
                        a.SweepLeaf.Script, a.InternalKey,
×
2911
                        a.TapscriptTree,
×
2912
                )), nil
×
2913

2914
        default:
×
2915
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2916
        }
2917
}
2918

2919
// Tree returns the underlying ScriptTree of the AnchorScriptTree.
2920
func (a *AnchorScriptTree) Tree() ScriptTree {
×
2921
        return a.ScriptTree
×
2922
}
×
2923

2924
// A compile time check to ensure AnchorScriptTree implements the
2925
// TapscriptDescriptor interface.
2926
var _ TapscriptDescriptor = (*AnchorScriptTree)(nil)
2927

2928
// TaprootOutputKeyAnchor returns the segwit v1 (taproot) witness program that
2929
// encodes the anchor output spending conditions: the passed key can be used
2930
// for keyspend, with the OP_CSV 16 clause living within an internal tapscript
2931
// leaf.
2932
//
2933
// Spend paths:
2934
//   - Key spend: <key_signature>
2935
//   - Script spend: OP_16 CSV <control_block>
2936
func TaprootOutputKeyAnchor(key *btcec.PublicKey) (*btcec.PublicKey, error) {
×
2937
        anchorScriptTree, err := NewAnchorScriptTree(key)
×
2938
        if err != nil {
×
2939
                return nil, err
×
2940
        }
×
2941

2942
        return anchorScriptTree.TaprootKey, nil
×
2943
}
2944

2945
// TaprootAnchorSpend constructs a valid witness allowing a node to sweep their
2946
// anchor output.
2947
func TaprootAnchorSpend(signer Signer, signDesc *SignDescriptor,
2948
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
2949

3✔
2950
        // For this spend type, we only need a single signature which'll be a
3✔
2951
        // keyspend using the anchor private key.
3✔
2952
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2953
        if err != nil {
3✔
2954
                return nil, err
×
2955
        }
×
2956

2957
        // The witness stack in this case is pretty simple: we only need to
2958
        // specify the signature generated.
2959
        witnessStack := make(wire.TxWitness, 1)
3✔
2960
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
3✔
2961

3✔
2962
        return witnessStack, nil
3✔
2963
}
2964

2965
// TaprootAnchorSpendAny constructs a valid witness allowing anyone to sweep
2966
// the anchor output after 16 blocks.
UNCOV
2967
func TaprootAnchorSpendAny(anchorKey *btcec.PublicKey) (wire.TxWitness, error) {
×
UNCOV
2968
        anchorScriptTree, err := NewAnchorScriptTree(anchorKey)
×
UNCOV
2969
        if err != nil {
×
2970
                return nil, err
×
2971
        }
×
2972

2973
        // For this spend, the only thing we need to do is create a valid
2974
        // control block. Other than that, there're no restrictions to how the
2975
        // output can be spent.
UNCOV
2976
        scriptTree := anchorScriptTree.TapscriptTree
×
UNCOV
2977
        sweepLeaf := anchorScriptTree.SweepLeaf
×
UNCOV
2978
        sweepIdx := scriptTree.LeafProofIndex[sweepLeaf.TapHash()]
×
UNCOV
2979
        sweepMerkleProof := scriptTree.LeafMerkleProofs[sweepIdx]
×
UNCOV
2980
        sweepControlBlock := sweepMerkleProof.ToControlBlock(anchorKey)
×
UNCOV
2981

×
UNCOV
2982
        // The final witness stack will be:
×
UNCOV
2983
        //
×
UNCOV
2984
        //  <sweep script> <control block>
×
UNCOV
2985
        witnessStack := make(wire.TxWitness, 2)
×
UNCOV
2986
        witnessStack[0] = sweepLeaf.Script
×
UNCOV
2987
        witnessStack[1], err = sweepControlBlock.ToBytes()
×
UNCOV
2988
        if err != nil {
×
2989
                return nil, err
×
2990
        }
×
2991

UNCOV
2992
        return witnessStack, nil
×
2993
}
2994

2995
// CommitSpendAnchor constructs a valid witness allowing a node to spend their
2996
// anchor output on the commitment transaction using their funding key. This is
2997
// used for the anchor channel type.
2998
func CommitSpendAnchor(signer Signer, signDesc *SignDescriptor,
2999
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
3000

3✔
3001
        if signDesc.KeyDesc.PubKey == nil {
3✔
3002
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
3003
                        "KeyDesc pubkey")
×
3004
        }
×
3005

3006
        // Create a signature.
3007
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
3008
        if err != nil {
3✔
3009
                return nil, err
×
3010
        }
×
3011

3012
        // The witness here is just a signature and the redeem script.
3013
        witnessStack := make([][]byte, 2)
3✔
3014
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
3✔
3015
        witnessStack[1] = signDesc.WitnessScript
3✔
3016

3✔
3017
        return witnessStack, nil
3✔
3018
}
3019

3020
// CommitSpendAnchorAnyone constructs a witness allowing anyone to spend the
3021
// anchor output after it has gotten 16 confirmations. Since no signing is
3022
// required, only knowledge of the redeem script is necessary to spend it.
UNCOV
3023
func CommitSpendAnchorAnyone(script []byte) (wire.TxWitness, error) {
×
UNCOV
3024
        // The witness here is just the redeem script.
×
UNCOV
3025
        witnessStack := make([][]byte, 2)
×
UNCOV
3026
        witnessStack[0] = nil
×
UNCOV
3027
        witnessStack[1] = script
×
UNCOV
3028

×
UNCOV
3029
        return witnessStack, nil
×
UNCOV
3030
}
×
3031

3032
// SingleTweakBytes computes set of bytes we call the single tweak. The purpose
3033
// of the single tweak is to randomize all regular delay and payment base
3034
// points. To do this, we generate a hash that binds the commitment point to
3035
// the pay/delay base point. The end result is that the basePoint is
3036
// tweaked as follows:
3037
//
3038
//   - key = basePoint + sha256(commitPoint || basePoint)*G
3039
func SingleTweakBytes(commitPoint, basePoint *btcec.PublicKey) []byte {
3✔
3040
        h := sha256.New()
3✔
3041
        h.Write(commitPoint.SerializeCompressed())
3✔
3042
        h.Write(basePoint.SerializeCompressed())
3✔
3043
        return h.Sum(nil)
3✔
3044
}
3✔
3045

3046
// TweakPubKey tweaks a public base point given a per commitment point. The per
3047
// commitment point is a unique point on our target curve for each commitment
3048
// transaction. When tweaking a local base point for use in a remote commitment
3049
// transaction, the remote party's current per commitment point is to be used.
3050
// The opposite applies for when tweaking remote keys. Precisely, the following
3051
// operation is used to "tweak" public keys:
3052
//
3053
//        tweakPub := basePoint + sha256(commitPoint || basePoint) * G
3054
//                 := G*k + sha256(commitPoint || basePoint)*G
3055
//                 := G*(k + sha256(commitPoint || basePoint))
3056
//
3057
// Therefore, if a party possess the value k, the private key of the base
3058
// point, then they are able to derive the proper private key for the
3059
// revokeKey by computing:
3060
//
3061
//        revokePriv := k + sha256(commitPoint || basePoint) mod N
3062
//
3063
// Where N is the order of the sub-group.
3064
//
3065
// The rationale for tweaking all public keys used within the commitment
3066
// contracts is to ensure that all keys are properly delinearized to avoid any
3067
// funny business when jointly collaborating to compute public and private
3068
// keys. Additionally, the use of the per commitment point ensures that each
3069
// commitment state houses a unique set of keys which is useful when creating
3070
// blinded channel outsourcing protocols.
3071
//
3072
// TODO(roasbeef): should be using double-scalar mult here
3073
func TweakPubKey(basePoint, commitPoint *btcec.PublicKey) *btcec.PublicKey {
3✔
3074
        tweakBytes := SingleTweakBytes(commitPoint, basePoint)
3✔
3075
        return TweakPubKeyWithTweak(basePoint, tweakBytes)
3✔
3076
}
3✔
3077

3078
// TweakPubKeyWithTweak is the exact same as the TweakPubKey function, however
3079
// it accepts the raw tweak bytes directly rather than the commitment point.
3080
func TweakPubKeyWithTweak(pubKey *btcec.PublicKey,
3081
        tweakBytes []byte) *btcec.PublicKey {
3✔
3082

3✔
3083
        var (
3✔
3084
                pubKeyJacobian btcec.JacobianPoint
3✔
3085
                tweakJacobian  btcec.JacobianPoint
3✔
3086
                resultJacobian btcec.JacobianPoint
3✔
3087
        )
3✔
3088
        tweakKey, _ := btcec.PrivKeyFromBytes(tweakBytes)
3✔
3089
        btcec.ScalarBaseMultNonConst(&tweakKey.Key, &tweakJacobian)
3✔
3090

3✔
3091
        pubKey.AsJacobian(&pubKeyJacobian)
3✔
3092
        btcec.AddNonConst(&pubKeyJacobian, &tweakJacobian, &resultJacobian)
3✔
3093

3✔
3094
        resultJacobian.ToAffine()
3✔
3095
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
3✔
3096
}
3✔
3097

3098
// TweakPrivKey tweaks the private key of a public base point given a per
3099
// commitment point. The per commitment secret is the revealed revocation
3100
// secret for the commitment state in question. This private key will only need
3101
// to be generated in the case that a channel counter party broadcasts a
3102
// revoked state. Precisely, the following operation is used to derive a
3103
// tweaked private key:
3104
//
3105
//   - tweakPriv := basePriv + sha256(commitment || basePub) mod N
3106
//
3107
// Where N is the order of the sub-group.
3108
func TweakPrivKey(basePriv *btcec.PrivateKey,
3109
        commitTweak []byte) *btcec.PrivateKey {
3✔
3110

3✔
3111
        // tweakInt := sha256(commitPoint || basePub)
3✔
3112
        tweakScalar := new(btcec.ModNScalar)
3✔
3113
        tweakScalar.SetByteSlice(commitTweak)
3✔
3114

3✔
3115
        tweakScalar.Add(&basePriv.Key)
3✔
3116

3✔
3117
        return &btcec.PrivateKey{Key: *tweakScalar}
3✔
3118
}
3✔
3119

3120
// DeriveRevocationPubkey derives the revocation public key given the
3121
// counterparty's commitment key, and revocation preimage derived via a
3122
// pseudo-random-function. In the event that we (for some reason) broadcast a
3123
// revoked commitment transaction, then if the other party knows the revocation
3124
// preimage, then they'll be able to derive the corresponding private key to
3125
// this private key by exploiting the homomorphism in the elliptic curve group:
3126
//   - https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
3127
//
3128
// The derivation is performed as follows:
3129
//
3130
//        revokeKey := revokeBase * sha256(revocationBase || commitPoint) +
3131
//                     commitPoint * sha256(commitPoint || revocationBase)
3132
//
3133
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint)) +
3134
//                     G*(commitSecret * sha256(commitPoint || revocationBase))
3135
//
3136
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint) +
3137
//                        commitSecret * sha256(commitPoint || revocationBase))
3138
//
3139
// Therefore, once we divulge the revocation secret, the remote peer is able to
3140
// compute the proper private key for the revokeKey by computing:
3141
//
3142
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3143
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3144
//
3145
// Where N is the order of the sub-group.
3146
func DeriveRevocationPubkey(revokeBase,
3147
        commitPoint *btcec.PublicKey) *btcec.PublicKey {
3✔
3148

3✔
3149
        // R = revokeBase * sha256(revocationBase || commitPoint)
3✔
3150
        revokeTweakBytes := SingleTweakBytes(revokeBase, commitPoint)
3✔
3151
        revokeTweakScalar := new(btcec.ModNScalar)
3✔
3152
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
3✔
3153

3✔
3154
        var (
3✔
3155
                revokeBaseJacobian btcec.JacobianPoint
3✔
3156
                rJacobian          btcec.JacobianPoint
3✔
3157
        )
3✔
3158
        revokeBase.AsJacobian(&revokeBaseJacobian)
3✔
3159
        btcec.ScalarMultNonConst(
3✔
3160
                revokeTweakScalar, &revokeBaseJacobian, &rJacobian,
3✔
3161
        )
3✔
3162

3✔
3163
        // C = commitPoint * sha256(commitPoint || revocationBase)
3✔
3164
        commitTweakBytes := SingleTweakBytes(commitPoint, revokeBase)
3✔
3165
        commitTweakScalar := new(btcec.ModNScalar)
3✔
3166
        commitTweakScalar.SetByteSlice(commitTweakBytes)
3✔
3167

3✔
3168
        var (
3✔
3169
                commitPointJacobian btcec.JacobianPoint
3✔
3170
                cJacobian           btcec.JacobianPoint
3✔
3171
        )
3✔
3172
        commitPoint.AsJacobian(&commitPointJacobian)
3✔
3173
        btcec.ScalarMultNonConst(
3✔
3174
                commitTweakScalar, &commitPointJacobian, &cJacobian,
3✔
3175
        )
3✔
3176

3✔
3177
        // Now that we have the revocation point, we add this to their commitment
3✔
3178
        // public key in order to obtain the revocation public key.
3✔
3179
        //
3✔
3180
        // P = R + C
3✔
3181
        var resultJacobian btcec.JacobianPoint
3✔
3182
        btcec.AddNonConst(&rJacobian, &cJacobian, &resultJacobian)
3✔
3183

3✔
3184
        resultJacobian.ToAffine()
3✔
3185
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
3✔
3186
}
3✔
3187

3188
// DeriveRevocationPrivKey derives the revocation private key given a node's
3189
// commitment private key, and the preimage to a previously seen revocation
3190
// hash. Using this derived private key, a node is able to claim the output
3191
// within the commitment transaction of a node in the case that they broadcast
3192
// a previously revoked commitment transaction.
3193
//
3194
// The private key is derived as follows:
3195
//
3196
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3197
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3198
//
3199
// Where N is the order of the sub-group.
3200
func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
3201
        commitSecret *btcec.PrivateKey) *btcec.PrivateKey {
3✔
3202

3✔
3203
        // r = sha256(revokeBasePub || commitPoint)
3✔
3204
        revokeTweakBytes := SingleTweakBytes(
3✔
3205
                revokeBasePriv.PubKey(), commitSecret.PubKey(),
3✔
3206
        )
3✔
3207
        revokeTweakScalar := new(btcec.ModNScalar)
3✔
3208
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
3✔
3209

3✔
3210
        // c = sha256(commitPoint || revokeBasePub)
3✔
3211
        commitTweakBytes := SingleTweakBytes(
3✔
3212
                commitSecret.PubKey(), revokeBasePriv.PubKey(),
3✔
3213
        )
3✔
3214
        commitTweakScalar := new(btcec.ModNScalar)
3✔
3215
        commitTweakScalar.SetByteSlice(commitTweakBytes)
3✔
3216

3✔
3217
        // Finally to derive the revocation secret key we'll perform the
3✔
3218
        // following operation:
3✔
3219
        //
3✔
3220
        //  k = (revocationPriv * r) + (commitSecret * c) mod N
3✔
3221
        //
3✔
3222
        // This works since:
3✔
3223
        //  P = (G*a)*b + (G*c)*d
3✔
3224
        //  P = G*(a*b) + G*(c*d)
3✔
3225
        //  P = G*(a*b + c*d)
3✔
3226
        revokeHalfPriv := revokeTweakScalar.Mul(&revokeBasePriv.Key)
3✔
3227
        commitHalfPriv := commitTweakScalar.Mul(&commitSecret.Key)
3✔
3228

3✔
3229
        revocationPriv := revokeHalfPriv.Add(commitHalfPriv)
3✔
3230

3✔
3231
        return &btcec.PrivateKey{Key: *revocationPriv}
3✔
3232
}
3✔
3233

3234
// ComputeCommitmentPoint generates a commitment point given a commitment
3235
// secret. The commitment point for each state is used to randomize each key in
3236
// the key-ring and also to used as a tweak to derive new public+private keys
3237
// for the state.
3238
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
3✔
3239
        _, pubKey := btcec.PrivKeyFromBytes(commitSecret)
3✔
3240
        return pubKey
3✔
3241
}
3✔
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