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

lightningnetwork / lnd / 10395438389

14 Aug 2024 09:42PM UTC coverage: 50.246% (-8.5%) from 58.725%
10395438389

Pull #9011

github

ziggie1984
multi: Add restriction of the ChanUpdate timestamp.

ChanUpdate timestamps are now restircted so that they cannot be
more than two weeks into the future. Moreover channels with both
timestamps in the ReplyChannelRange msg either too far in the past
or too far in the future are not queried.
Pull Request #9011: Fix TimeStamp issue in the Gossip Syncer

29 of 45 new or added lines in 3 files covered. (64.44%)

23069 existing lines in 396 files now uncovered.

96101 of 191260 relevant lines covered (50.25%)

2.08 hits per line

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

77.36
/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/txscript"
15
        "github.com/btcsuite/btcd/wire"
16
        "github.com/lightningnetwork/lnd/lntypes"
17
        "github.com/lightningnetwork/lnd/lnutils"
18
        "golang.org/x/crypto/ripemd160"
19
)
20

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

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

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

38
        pub, err := btcec.ParsePubKey(pubBytes)
4✔
39
        if err != nil {
4✔
40
                panic(err)
×
41
        }
42

43
        return *pub
4✔
44
}
45

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

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

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

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

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

78
        return ecdsa.ParseDERSignature(rawSig)
4✔
79
}
80

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

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

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

4✔
102
        bldr.AddOp(txscript.OP_0)
4✔
103
        pkhash := btcutil.Hash160(pubkey)
4✔
104
        bldr.AddData(pkhash)
4✔
105
        return bldr.Script()
4✔
106
}
4✔
107

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

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

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

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

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

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

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

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

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

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

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

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

198
        return witnessScript, wire.NewTxOut(amt, pkScript), nil
4✔
199
}
200

201
// GenTaprootFundingScript constructs the taproot-native funding output that
202
// uses musig2 to create a single aggregated key to anchor the channel.
203
func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
204
        amt int64) ([]byte, *wire.TxOut, error) {
4✔
205

4✔
206
        // Similar to the existing p2wsh funding script, we'll always make sure
4✔
207
        // we sort the keys before any major operations. In order to ensure
4✔
208
        // that there's no other way this output can be spent, we'll use a BIP
4✔
209
        // 86 tweak here during aggregation.
4✔
210
        //
4✔
211
        // TODO(roasbeef): revisit if BIP 86 is needed here?
4✔
212
        combinedKey, _, _, err := musig2.AggregateKeys(
4✔
213
                []*btcec.PublicKey{aPub, bPub}, true,
4✔
214
                musig2.WithBIP86KeyTweak(),
4✔
215
        )
4✔
216
        if err != nil {
4✔
217
                return nil, nil, fmt.Errorf("unable to combine keys: %w", err)
×
218
        }
×
219

220
        // Now that we have the combined key, we can create a taproot pkScript
221
        // from this, and then make the txout given the amount.
222
        pkScript, err := PayToTaprootScript(combinedKey.FinalKey)
4✔
223
        if err != nil {
4✔
224
                return nil, nil, fmt.Errorf("unable to make taproot "+
×
225
                        "pkscript: %w", err)
×
226
        }
×
227

228
        txOut := wire.NewTxOut(amt, pkScript)
4✔
229

4✔
230
        // For the "witness program" we just return the raw pkScript since the
4✔
231
        // output we create can _only_ be spent with a musig2 signature.
4✔
232
        return pkScript, txOut, nil
4✔
233
}
234

235
// SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh
236
// multi-sig output.
237
func SpendMultiSig(witnessScript, pubA []byte, sigA Signature,
238
        pubB []byte, sigB Signature) [][]byte {
4✔
239

4✔
240
        witness := make([][]byte, 4)
4✔
241

4✔
242
        // When spending a p2wsh multi-sig script, rather than an OP_0, we add
4✔
243
        // a nil stack element to eat the extra pop.
4✔
244
        witness[0] = nil
4✔
245

4✔
246
        // When initially generating the witnessScript, we sorted the serialized
4✔
247
        // public keys in descending order. So we do a quick comparison in order
4✔
248
        // ensure the signatures appear on the Script Virtual Machine stack in
4✔
249
        // the correct order.
4✔
250
        if bytes.Compare(pubA, pubB) == 1 {
8✔
251
                witness[1] = append(sigB.Serialize(), byte(txscript.SigHashAll))
4✔
252
                witness[2] = append(sigA.Serialize(), byte(txscript.SigHashAll))
4✔
253
        } else {
8✔
254
                witness[1] = append(sigA.Serialize(), byte(txscript.SigHashAll))
4✔
255
                witness[2] = append(sigB.Serialize(), byte(txscript.SigHashAll))
4✔
256
        }
4✔
257

258
        // Finally, add the preimage as the last witness element.
259
        witness[3] = witnessScript
4✔
260

4✔
261
        return witness
4✔
262
}
263

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

280
        return found, index
4✔
281
}
282

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

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

4✔
335
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
336
                OfferedHtlcScriptSizeConfirmed,
4✔
337
        ))
4✔
338

4✔
339
        // The opening operations are used to determine if this is the receiver
4✔
340
        // of the HTLC attempting to sweep all the funds due to a contract
4✔
341
        // breach. In this case, they'll place the revocation key at the top of
4✔
342
        // the stack.
4✔
343
        builder.AddOp(txscript.OP_DUP)
4✔
344
        builder.AddOp(txscript.OP_HASH160)
4✔
345
        builder.AddData(btcutil.Hash160(revocationKey.SerializeCompressed()))
4✔
346
        builder.AddOp(txscript.OP_EQUAL)
4✔
347

4✔
348
        // If the hash matches, then this is the revocation clause. The output
4✔
349
        // can be spent if the check sig operation passes.
4✔
350
        builder.AddOp(txscript.OP_IF)
4✔
351
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
352

4✔
353
        // Otherwise, this may either be the receiver of the HTLC claiming with
4✔
354
        // the pre-image, or the sender of the HTLC sweeping the output after
4✔
355
        // it has timed out.
4✔
356
        builder.AddOp(txscript.OP_ELSE)
4✔
357

4✔
358
        // We'll do a bit of set up by pushing the receiver's key on the top of
4✔
359
        // the stack. This will be needed later if we decide that this is the
4✔
360
        // sender activating the time out clause with the HTLC timeout
4✔
361
        // transaction.
4✔
362
        builder.AddData(receiverHtlcKey.SerializeCompressed())
4✔
363

4✔
364
        // Atm, the top item of the stack is the receiverKey's so we use a swap
4✔
365
        // to expose what is either the payment pre-image or a signature.
4✔
366
        builder.AddOp(txscript.OP_SWAP)
4✔
367

4✔
368
        // With the top item swapped, check if it's 32 bytes. If so, then this
4✔
369
        // *may* be the payment pre-image.
4✔
370
        builder.AddOp(txscript.OP_SIZE)
4✔
371
        builder.AddInt64(32)
4✔
372
        builder.AddOp(txscript.OP_EQUAL)
4✔
373

4✔
374
        // If it isn't then this might be the sender of the HTLC activating the
4✔
375
        // time out clause.
4✔
376
        builder.AddOp(txscript.OP_NOTIF)
4✔
377

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

4✔
389
        // Otherwise, then the only other case is that this is the receiver of
4✔
390
        // the HTLC sweeping it on-chain with the payment pre-image.
4✔
391
        builder.AddOp(txscript.OP_ELSE)
4✔
392

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

4✔
402
        // This checks the receiver's signature so that a third party with
4✔
403
        // knowledge of the payment preimage still cannot steal the output.
4✔
404
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
405

4✔
406
        // Close out the OP_IF statement above.
4✔
407
        builder.AddOp(txscript.OP_ENDIF)
4✔
408

4✔
409
        // Add 1 block CSV delay if a confirmation is required for the
4✔
410
        // non-revocation clauses.
4✔
411
        if confirmedSpend {
8✔
412
                builder.AddOp(txscript.OP_1)
4✔
413
                builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
414
                builder.AddOp(txscript.OP_DROP)
4✔
415
        }
4✔
416

417
        // Close out the OP_IF statement at the top of the script.
418
        builder.AddOp(txscript.OP_ENDIF)
4✔
419

4✔
420
        return builder.Script()
4✔
421
}
422

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

×
UNCOV
433
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
434
        if err != nil {
×
435
                return nil, err
×
436
        }
×
437

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

×
UNCOV
448
        return witnessStack, nil
×
449
}
450

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

×
UNCOV
461
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
462
        if err != nil {
×
463
                return nil, err
×
464
        }
×
465

UNCOV
466
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
×
467
}
468

469
// IsHtlcSpendRevoke is used to determine if the passed spend is spending a
470
// HTLC output using the revocation key.
471
func IsHtlcSpendRevoke(txIn *wire.TxIn, signDesc *SignDescriptor) (
472
        bool, error) {
4✔
473

4✔
474
        // For taproot channels, the revocation path only has a single witness,
4✔
475
        // as that's the key spend path.
4✔
476
        isTaproot := txscript.IsPayToTaproot(signDesc.Output.PkScript)
4✔
477
        if isTaproot {
8✔
478
                return len(txIn.Witness) == 1, nil
4✔
479
        }
4✔
480

UNCOV
481
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
482
        if err != nil {
×
483
                return false, err
×
484
        }
×
485

UNCOV
486
        if len(txIn.Witness) == 3 &&
×
UNCOV
487
                bytes.Equal(txIn.Witness[1], revokeKey.SerializeCompressed()) {
×
UNCOV
488

×
UNCOV
489
                return true, nil
×
UNCOV
490
        }
×
491

UNCOV
492
        return false, nil
×
493
}
494

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

4✔
503
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
504
        if err != nil {
4✔
505
                return nil, err
×
506
        }
×
507

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

4✔
516
        return witnessStack, nil
4✔
517
}
518

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

4✔
528
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
4✔
529
        if err != nil {
4✔
530
                return nil, err
×
531
        }
×
532

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

4✔
544
        return witnessStack, nil
4✔
545
}
546

547
// SenderHTLCTapLeafTimeout returns the full tapscript leaf for the timeout
548
// path of the sender HTLC. This is a small script that allows the sender to
549
// timeout the HTLC after a period of time:
550
//
551
//        <local_key> OP_CHECKSIGVERIFY
552
//        <remote_key> OP_CHECKSIG
553
func SenderHTLCTapLeafTimeout(senderHtlcKey,
554
        receiverHtlcKey *btcec.PublicKey) (txscript.TapLeaf, error) {
4✔
555

4✔
556
        builder := txscript.NewScriptBuilder()
4✔
557

4✔
558
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
4✔
559
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
4✔
560
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
4✔
561
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
562

4✔
563
        timeoutLeafScript, err := builder.Script()
4✔
564
        if err != nil {
4✔
565
                return txscript.TapLeaf{}, err
×
566
        }
×
567

568
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
4✔
569
}
570

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

4✔
582
        builder := txscript.NewScriptBuilder()
4✔
583

4✔
584
        // Check that the pre-image is 32 bytes as required.
4✔
585
        builder.AddOp(txscript.OP_SIZE)
4✔
586
        builder.AddInt64(32)
4✔
587
        builder.AddOp(txscript.OP_EQUALVERIFY)
4✔
588

4✔
589
        // Check that the specified pre-image matches what we hard code into
4✔
590
        // the script.
4✔
591
        builder.AddOp(txscript.OP_HASH160)
4✔
592
        builder.AddData(Ripemd160H(paymentHash))
4✔
593
        builder.AddOp(txscript.OP_EQUALVERIFY)
4✔
594

4✔
595
        // Verify the remote party's signature, then make them wait 1 block
4✔
596
        // after confirmation to properly sweep.
4✔
597
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
4✔
598
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
599
        builder.AddOp(txscript.OP_1)
4✔
600
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
601
        builder.AddOp(txscript.OP_DROP)
4✔
602

4✔
603
        successLeafScript, err := builder.Script()
4✔
604
        if err != nil {
4✔
605
                return txscript.TapLeaf{}, err
×
606
        }
×
607

608
        return txscript.NewBaseTapLeaf(successLeafScript), nil
4✔
609
}
610

611
// htlcType is an enum value that denotes what type of HTLC script this is.
612
type htlcType uint8
613

614
const (
615
        // htlcLocalIncoming represents an incoming HTLC on the local
616
        // commitment transaction.
617
        htlcLocalIncoming htlcType = iota
618

619
        // htlcLocalOutgoing represents an outgoing HTLC on the local
620
        // commitment transaction.
621
        htlcLocalOutgoing
622

623
        // htlcRemoteIncoming represents an incoming HTLC on the remote
624
        // commitment transaction.
625
        htlcRemoteIncoming
626

627
        // htlcRemoteOutgoing represents an outgoing HTLC on the remote
628
        // commitment transaction.
629
        htlcRemoteOutgoing
630
)
631

632
// HtlcScriptTree holds the taproot output key, as well as the two script path
633
// leaves that every taproot HTLC script depends on.
634
type HtlcScriptTree struct {
635
        ScriptTree
636

637
        // SuccessTapLeaf is the tapleaf for the redemption path.
638
        SuccessTapLeaf txscript.TapLeaf
639

640
        // TimeoutTapLeaf is the tapleaf for the timeout path.
641
        TimeoutTapLeaf txscript.TapLeaf
642

643
        htlcType htlcType
644
}
645

646
// WitnessScriptToSign returns the witness script that we'll use when signing
647
// for the remote party, and also verifying signatures on our transactions. As
648
// an example, when we create an outgoing HTLC for the remote party, we want to
649
// sign the success path for them, so we'll return the success path leaf.
650
func (h *HtlcScriptTree) WitnessScriptToSign() []byte {
4✔
651
        switch h.htlcType {
4✔
652
        // For incoming HLTCs on our local commitment, we care about verifying
653
        // the success path.
654
        case htlcLocalIncoming:
4✔
655
                return h.SuccessTapLeaf.Script
4✔
656

657
        // For incoming HTLCs on the remote party's commitment, we want to sign
658
        // the timeout path for them.
659
        case htlcRemoteIncoming:
4✔
660
                return h.TimeoutTapLeaf.Script
4✔
661

662
        // For outgoing HTLCs on our local commitment, we want to verify the
663
        // timeout path.
664
        case htlcLocalOutgoing:
4✔
665
                return h.TimeoutTapLeaf.Script
4✔
666

667
        // For outgoing HTLCs on the remote party's commitment, we want to sign
668
        // the success path for them.
669
        case htlcRemoteOutgoing:
4✔
670
                return h.SuccessTapLeaf.Script
4✔
671

672
        default:
×
673
                panic(fmt.Sprintf("unknown htlc type: %v", h.htlcType))
×
674
        }
675
}
676

677
// WitnessScriptForPath returns the witness script for the given spending path.
678
// An error is returned if the path is unknown.
679
func (h *HtlcScriptTree) WitnessScriptForPath(path ScriptPath) ([]byte, error) {
4✔
680
        switch path {
4✔
681
        case ScriptPathSuccess:
4✔
682
                return h.SuccessTapLeaf.Script, nil
4✔
683
        case ScriptPathTimeout:
4✔
684
                return h.TimeoutTapLeaf.Script, nil
4✔
685
        default:
×
686
                return nil, fmt.Errorf("unknown script path: %v", path)
×
687
        }
688
}
689

690
// CtrlBlockForPath returns the control block for the given spending path. For
691
// script types that don't have a control block, nil is returned.
692
func (h *HtlcScriptTree) CtrlBlockForPath(path ScriptPath,
693
) (*txscript.ControlBlock, error) {
4✔
694

4✔
695
        switch path {
4✔
696
        case ScriptPathSuccess:
4✔
697
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
698
                        h.SuccessTapLeaf.Script, h.InternalKey,
4✔
699
                        h.TapscriptTree,
4✔
700
                )), nil
4✔
701
        case ScriptPathTimeout:
4✔
702
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
703
                        h.TimeoutTapLeaf.Script, h.InternalKey,
4✔
704
                        h.TapscriptTree,
4✔
705
                )), nil
4✔
706
        default:
×
707
                return nil, fmt.Errorf("unknown script path: %v", path)
×
708
        }
709
}
710

711
// A compile time check to ensure HtlcScriptTree implements the
712
// TapscriptMultiplexer interface.
713
var _ TapscriptDescriptor = (*HtlcScriptTree)(nil)
714

715
// senderHtlcTapScriptTree builds the tapscript tree which is used to anchor
716
// the HTLC key for HTLCs on the sender's commitment.
717
func senderHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
718
        revokeKey *btcec.PublicKey, payHash []byte,
719
        hType htlcType) (*HtlcScriptTree, error) {
4✔
720

4✔
721
        // First, we'll obtain the tap leaves for both the success and timeout
4✔
722
        // path.
4✔
723
        successTapLeaf, err := SenderHTLCTapLeafSuccess(
4✔
724
                receiverHtlcKey, payHash,
4✔
725
        )
4✔
726
        if err != nil {
4✔
727
                return nil, err
×
728
        }
×
729
        timeoutTapLeaf, err := SenderHTLCTapLeafTimeout(
4✔
730
                senderHtlcKey, receiverHtlcKey,
4✔
731
        )
4✔
732
        if err != nil {
4✔
733
                return nil, err
×
734
        }
×
735

736
        // With the two leaves obtained, we'll now make the tapscript tree,
737
        // then obtain the root from that
738
        tapscriptTree := txscript.AssembleTaprootScriptTree(
4✔
739
                successTapLeaf, timeoutTapLeaf,
4✔
740
        )
4✔
741

4✔
742
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
4✔
743

4✔
744
        // With the tapscript root obtained, we'll tweak the revocation key
4✔
745
        // with this value to obtain the key that HTLCs will be sent to.
4✔
746
        htlcKey := txscript.ComputeTaprootOutputKey(
4✔
747
                revokeKey, tapScriptRoot[:],
4✔
748
        )
4✔
749

4✔
750
        return &HtlcScriptTree{
4✔
751
                ScriptTree: ScriptTree{
4✔
752
                        TaprootKey:    htlcKey,
4✔
753
                        TapscriptTree: tapscriptTree,
4✔
754
                        TapscriptRoot: tapScriptRoot[:],
4✔
755
                        InternalKey:   revokeKey,
4✔
756
                },
4✔
757
                SuccessTapLeaf: successTapLeaf,
4✔
758
                TimeoutTapLeaf: timeoutTapLeaf,
4✔
759
                htlcType:       hType,
4✔
760
        }, nil
4✔
761
}
762

763
// SenderHTLCScriptTaproot constructs the taproot witness program (schnorr key)
764
// for an outgoing HTLC on the sender's version of the commitment transaction.
765
// This method returns the top level tweaked public key that commits to both
766
// the script paths. This is also known as an offered HTLC.
767
//
768
// The returned key commits to a tapscript tree with two possible paths:
769
//
770
//   - Timeout path:
771
//     <local_key> OP_CHECKSIGVERIFY
772
//     <remote_key> OP_CHECKSIG
773
//
774
//   - Success path:
775
//     OP_SIZE 32 OP_EQUALVERIFY
776
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
777
//     <remote_htlcpubkey> OP_CHECKSIG
778
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
779
//
780
// The timeout path can be spent with a witness of (sender timeout):
781
//
782
//        <receiver sig> <local sig> <timeout_script> <control_block>
783
//
784
// The success path can be spent with a valid control block, and a witness of
785
// (receiver redeem):
786
//
787
//        <receiver sig> <preimage> <success_script> <control_block>
788
//
789
// The top level keyspend key is the revocation key, which allows a defender to
790
// unilaterally spend the created output.
791
func SenderHTLCScriptTaproot(senderHtlcKey, receiverHtlcKey,
792
        revokeKey *btcec.PublicKey, payHash []byte,
793
        whoseCommit lntypes.ChannelParty) (*HtlcScriptTree, error) {
4✔
794

4✔
795
        var hType htlcType
4✔
796
        if whoseCommit.IsLocal() {
8✔
797
                hType = htlcLocalOutgoing
4✔
798
        } else {
8✔
799
                hType = htlcRemoteIncoming
4✔
800
        }
4✔
801

802
        // Given all the necessary parameters, we'll return the HTLC script
803
        // tree that includes the top level output script, as well as the two
804
        // tap leaf paths.
805
        return senderHtlcTapScriptTree(
4✔
806
                senderHtlcKey, receiverHtlcKey, revokeKey, payHash,
4✔
807
                hType,
4✔
808
        )
4✔
809
}
810

811
// maybeAppendSighashType appends a sighash type to the end of a signature if
812
// the sighash type isn't sighash default.
813
func maybeAppendSighash(sig Signature, sigHash txscript.SigHashType) []byte {
4✔
814
        sigBytes := sig.Serialize()
4✔
815
        if sigHash == txscript.SigHashDefault {
8✔
816
                return sigBytes
4✔
817
        }
4✔
818

819
        return append(sigBytes, byte(sigHash))
4✔
820
}
821

822
// SenderHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
823
// sender taproot HTLC with the pre-image. The returned witness is valid and
824
// includes the control block required to spend the output. This is the offered
825
// HTLC claimed by the remote party.
826
func SenderHTLCScriptTaprootRedeem(signer Signer, signDesc *SignDescriptor,
827
        sweepTx *wire.MsgTx, preimage []byte, revokeKey *btcec.PublicKey,
828
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
829

4✔
830
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
831
        if err != nil {
4✔
832
                return nil, err
×
833
        }
×
834

835
        // In addition to the signature and the witness/leaf script, we also
836
        // need to make a control block proof using the tapscript tree.
837
        var ctrlBlock []byte
4✔
838
        if signDesc.ControlBlock == nil {
4✔
UNCOV
839
                successControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
840
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
841
                )
×
UNCOV
842

×
UNCOV
843
                ctrlBytes, err := successControlBlock.ToBytes()
×
UNCOV
844
                if err != nil {
×
845
                        return nil, err
×
846
                }
×
847

UNCOV
848
                ctrlBlock = ctrlBytes
×
849
        } else {
4✔
850
                ctrlBlock = signDesc.ControlBlock
4✔
851
        }
4✔
852

853
        // The final witness stack is:
854
        //  <receiver sig> <preimage> <success_script> <control_block>
855
        witnessStack := make(wire.TxWitness, 4)
4✔
856
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
857
        witnessStack[1] = preimage
4✔
858
        witnessStack[2] = signDesc.WitnessScript
4✔
859
        witnessStack[3] = ctrlBlock
4✔
860

4✔
861
        return witnessStack, nil
4✔
862
}
863

864
// SenderHTLCScriptTaprootTimeout creates a valid witness needed to timeout an
865
// HTLC on the sender's commitment transaction. The returned witness is valid
866
// and includes the control block required to spend the output. This is a
867
// timeout of the offered HTLC by the sender.
868
func SenderHTLCScriptTaprootTimeout(receiverSig Signature,
869
        receiverSigHash txscript.SigHashType, signer Signer,
870
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx,
871
        revokeKey *btcec.PublicKey,
872
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
873

4✔
874
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
4✔
875
        if err != nil {
4✔
876
                return nil, err
×
877
        }
×
878

879
        // With the sweep signature obtained, we'll obtain the control block
880
        // proof needed to perform a valid spend for the timeout path.
881
        var ctrlBlockBytes []byte
4✔
882
        if signDesc.ControlBlock == nil {
8✔
883
                timeoutControlBlock := MakeTaprootCtrlBlock(
4✔
884
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
4✔
885
                )
4✔
886
                ctrlBytes, err := timeoutControlBlock.ToBytes()
4✔
887
                if err != nil {
4✔
888
                        return nil, err
×
889
                }
×
890

891
                ctrlBlockBytes = ctrlBytes
4✔
892
        } else {
4✔
893
                ctrlBlockBytes = signDesc.ControlBlock
4✔
894
        }
4✔
895

896
        // The final witness stack is:
897
        //  <receiver sig> <local sig> <timeout_script> <control_block>
898
        witnessStack := make(wire.TxWitness, 4)
4✔
899
        witnessStack[0] = maybeAppendSighash(receiverSig, receiverSigHash)
4✔
900
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
901
        witnessStack[2] = signDesc.WitnessScript
4✔
902
        witnessStack[3] = ctrlBlockBytes
4✔
903

4✔
904
        return witnessStack, nil
4✔
905
}
906

907
// SenderHTLCScriptTaprootRevoke creates a valid witness needed to spend the
908
// revocation path of the HTLC. This uses a plain keyspend using the specified
909
// revocation key.
910
func SenderHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
911
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
912

4✔
913
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
914
        if err != nil {
4✔
915
                return nil, err
×
916
        }
×
917

918
        // The witness stack in this case is pretty simple: we only need to
919
        // specify the signature generated.
920
        witnessStack := make(wire.TxWitness, 1)
4✔
921
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
922

4✔
923
        return witnessStack, nil
4✔
924
}
925

926
// ReceiverHTLCScript constructs the public key script for an incoming HTLC
927
// output payment for the receiver's version of the commitment transaction. The
928
// possible execution paths from this script include:
929
//   - The receiver of the HTLC uses its second level HTLC transaction to
930
//     advance the state of the HTLC into the delay+claim state.
931
//   - The sender of the HTLC sweeps all the funds of the HTLC as a breached
932
//     commitment was broadcast.
933
//   - The sender of the HTLC sweeps the HTLC on-chain after the timeout period
934
//     of the HTLC has passed.
935
//
936
// If confirmedSpend=true, a 1 OP_CSV check will be added to the non-revocation
937
// cases, to allow sweeping only after confirmation.
938
//
939
// Possible Input Scripts:
940
//
941
//        RECVR: <0> <sender sig> <recvr sig> <preimage> (spend using HTLC success transaction)
942
//        REVOK: <sig> <key>
943
//        SENDR: <sig> 0
944
//
945
// Received HTLC Output Script:
946
//
947
//         OP_DUP OP_HASH160 <revocation key hash160> OP_EQUAL
948
//         OP_IF
949
//                 OP_CHECKSIG
950
//         OP_ELSE
951
//                <sendr htlc key>
952
//                OP_SWAP OP_SIZE 32 OP_EQUAL
953
//                OP_IF
954
//                    OP_HASH160 <ripemd160(payment hash)> OP_EQUALVERIFY
955
//                    2 OP_SWAP <recvr htlc key> 2 OP_CHECKMULTISIG
956
//                OP_ELSE
957
//                    OP_DROP <cltv expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
958
//                    OP_CHECKSIG
959
//                OP_ENDIF
960
//                [1 OP_CHECKSEQUENCEVERIFY OP_DROP] <- if allowing confirmed
961
//                spend only.
962
//         OP_ENDIF
963
func ReceiverHTLCScript(cltvExpiry uint32, senderHtlcKey,
964
        receiverHtlcKey, revocationKey *btcec.PublicKey,
965
        paymentHash []byte, confirmedSpend bool) ([]byte, error) {
4✔
966

4✔
967
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
968
                AcceptedHtlcScriptSizeConfirmed,
4✔
969
        ))
4✔
970

4✔
971
        // The opening operations are used to determine if this is the sender
4✔
972
        // of the HTLC attempting to sweep all the funds due to a contract
4✔
973
        // breach. In this case, they'll place the revocation key at the top of
4✔
974
        // the stack.
4✔
975
        builder.AddOp(txscript.OP_DUP)
4✔
976
        builder.AddOp(txscript.OP_HASH160)
4✔
977
        builder.AddData(btcutil.Hash160(revocationKey.SerializeCompressed()))
4✔
978
        builder.AddOp(txscript.OP_EQUAL)
4✔
979

4✔
980
        // If the hash matches, then this is the revocation clause. The output
4✔
981
        // can be spent if the check sig operation passes.
4✔
982
        builder.AddOp(txscript.OP_IF)
4✔
983
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
984

4✔
985
        // Otherwise, this may either be the receiver of the HTLC starting the
4✔
986
        // claiming process via the second level HTLC success transaction and
4✔
987
        // the pre-image, or the sender of the HTLC sweeping the output after
4✔
988
        // it has timed out.
4✔
989
        builder.AddOp(txscript.OP_ELSE)
4✔
990

4✔
991
        // We'll do a bit of set up by pushing the sender's key on the top of
4✔
992
        // the stack. This will be needed later if we decide that this is the
4✔
993
        // receiver transitioning the output to the claim state using their
4✔
994
        // second-level HTLC success transaction.
4✔
995
        builder.AddData(senderHtlcKey.SerializeCompressed())
4✔
996

4✔
997
        // Atm, the top item of the stack is the sender's key so we use a swap
4✔
998
        // to expose what is either the payment pre-image or something else.
4✔
999
        builder.AddOp(txscript.OP_SWAP)
4✔
1000

4✔
1001
        // With the top item swapped, check if it's 32 bytes. If so, then this
4✔
1002
        // *may* be the payment pre-image.
4✔
1003
        builder.AddOp(txscript.OP_SIZE)
4✔
1004
        builder.AddInt64(32)
4✔
1005
        builder.AddOp(txscript.OP_EQUAL)
4✔
1006

4✔
1007
        // If the item on the top of the stack is 32-bytes, then it is the
4✔
1008
        // proper size, so this indicates that the receiver of the HTLC is
4✔
1009
        // attempting to claim the output on-chain by transitioning the state
4✔
1010
        // of the HTLC to delay+claim.
4✔
1011
        builder.AddOp(txscript.OP_IF)
4✔
1012

4✔
1013
        // Next we'll hash the item on the top of the stack, if it matches the
4✔
1014
        // payment pre-image, then we'll continue. Otherwise, we'll end the
4✔
1015
        // script here as this is the invalid payment pre-image.
4✔
1016
        builder.AddOp(txscript.OP_HASH160)
4✔
1017
        builder.AddData(Ripemd160H(paymentHash))
4✔
1018
        builder.AddOp(txscript.OP_EQUALVERIFY)
4✔
1019

4✔
1020
        // If the payment hash matches, then we'll also need to satisfy the
4✔
1021
        // multi-sig covenant by providing both signatures of the sender and
4✔
1022
        // receiver. If the convenient is met, then we'll allow the spending of
4✔
1023
        // this output, but only by the HTLC success transaction.
4✔
1024
        builder.AddOp(txscript.OP_2)
4✔
1025
        builder.AddOp(txscript.OP_SWAP)
4✔
1026
        builder.AddData(receiverHtlcKey.SerializeCompressed())
4✔
1027
        builder.AddOp(txscript.OP_2)
4✔
1028
        builder.AddOp(txscript.OP_CHECKMULTISIG)
4✔
1029

4✔
1030
        // Otherwise, this might be the sender of the HTLC attempting to sweep
4✔
1031
        // it on-chain after the timeout.
4✔
1032
        builder.AddOp(txscript.OP_ELSE)
4✔
1033

4✔
1034
        // We'll drop the extra item (which is the output from evaluating the
4✔
1035
        // OP_EQUAL) above from the stack.
4✔
1036
        builder.AddOp(txscript.OP_DROP)
4✔
1037

4✔
1038
        // With that item dropped off, we can now enforce the absolute
4✔
1039
        // lock-time required to timeout the HTLC. If the time has passed, then
4✔
1040
        // we'll proceed with a checksig to ensure that this is actually the
4✔
1041
        // sender of he original HTLC.
4✔
1042
        builder.AddInt64(int64(cltvExpiry))
4✔
1043
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
4✔
1044
        builder.AddOp(txscript.OP_DROP)
4✔
1045
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1046

4✔
1047
        // Close out the inner if statement.
4✔
1048
        builder.AddOp(txscript.OP_ENDIF)
4✔
1049

4✔
1050
        // Add 1 block CSV delay for non-revocation clauses if confirmation is
4✔
1051
        // required.
4✔
1052
        if confirmedSpend {
8✔
1053
                builder.AddOp(txscript.OP_1)
4✔
1054
                builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
1055
                builder.AddOp(txscript.OP_DROP)
4✔
1056
        }
4✔
1057

1058
        // Close out the outer if statement.
1059
        builder.AddOp(txscript.OP_ENDIF)
4✔
1060

4✔
1061
        return builder.Script()
4✔
1062
}
1063

1064
// ReceiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
1065
// an HTLC to redeem the conditional payment in the event that their commitment
1066
// transaction is broadcast. This clause transitions the state of the HLTC
1067
// output into the delay+claim state by activating the off-chain covenant bound
1068
// by the 2-of-2 multi-sig output. The HTLC success timeout transaction being
1069
// signed has a relative timelock delay enforced by its sequence number. This
1070
// delay give the sender of the HTLC enough time to revoke the output if this
1071
// is a breach commitment transaction.
1072
func ReceiverHtlcSpendRedeem(senderSig Signature,
1073
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1074
        signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
1075
        wire.TxWitness, error) {
4✔
1076

4✔
1077
        // First, we'll generate a signature for the HTLC success transaction.
4✔
1078
        // The signDesc should be signing with the public key used as the
4✔
1079
        // receiver's public key and also the correct single tweak.
4✔
1080
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
4✔
1081
        if err != nil {
4✔
1082
                return nil, err
×
1083
        }
×
1084

1085
        // The final witness stack is used the provide the script with the
1086
        // payment pre-image, and also execute the multi-sig clause after the
1087
        // pre-images matches. We add a nil item at the bottom of the stack in
1088
        // order to consume the extra pop within OP_CHECKMULTISIG.
1089
        witnessStack := wire.TxWitness(make([][]byte, 5))
4✔
1090
        witnessStack[0] = nil
4✔
1091
        witnessStack[1] = append(senderSig.Serialize(), byte(senderSigHash))
4✔
1092
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
1093
        witnessStack[3] = paymentPreimage
4✔
1094
        witnessStack[4] = signDesc.WitnessScript
4✔
1095

4✔
1096
        return witnessStack, nil
4✔
1097
}
1098

1099
// ReceiverHtlcSpendRevokeWithKey constructs a valid witness allowing the sender of an
1100
// HTLC within a previously revoked commitment transaction to re-claim the
1101
// pending funds in the case that the receiver broadcasts this revoked
1102
// commitment transaction.
1103
func ReceiverHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
UNCOV
1104
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1105

×
UNCOV
1106
        // First, we'll generate a signature for the sweep transaction.  The
×
UNCOV
1107
        // signDesc should be signing with the public key used as the fully
×
UNCOV
1108
        // derived revocation public key and also the correct double tweak
×
UNCOV
1109
        // value.
×
UNCOV
1110
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
1111
        if err != nil {
×
1112
                return nil, err
×
1113
        }
×
1114

1115
        // We place a zero, then one as the first items in the evaluated
1116
        // witness stack in order to force script execution to the HTLC
1117
        // revocation clause.
UNCOV
1118
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1119
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1120
        witnessStack[1] = revokeKey.SerializeCompressed()
×
UNCOV
1121
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1122

×
UNCOV
1123
        return witnessStack, nil
×
1124
}
1125

UNCOV
1126
func deriveRevokePubKey(signDesc *SignDescriptor) (*btcec.PublicKey, error) {
×
UNCOV
1127
        if signDesc.KeyDesc.PubKey == nil {
×
1128
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
1129
                        "KeyDesc pubkey")
×
1130
        }
×
1131

1132
        // Derive the revocation key using the local revocation base point and
1133
        // commitment point.
UNCOV
1134
        revokeKey := DeriveRevocationPubkey(
×
UNCOV
1135
                signDesc.KeyDesc.PubKey,
×
UNCOV
1136
                signDesc.DoubleTweak.PubKey(),
×
UNCOV
1137
        )
×
UNCOV
1138

×
UNCOV
1139
        return revokeKey, nil
×
1140
}
1141

1142
// ReceiverHtlcSpendRevoke constructs a valid witness allowing the sender of an
1143
// HTLC within a previously revoked commitment transaction to re-claim the
1144
// pending funds in the case that the receiver broadcasts this revoked
1145
// commitment transaction. This method first derives the appropriate revocation
1146
// key, and requires that the provided SignDescriptor has a local revocation
1147
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
1148
// respectively.
1149
func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1150
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1151

×
UNCOV
1152
        revokeKey, err := deriveRevokePubKey(signDesc)
×
UNCOV
1153
        if err != nil {
×
1154
                return nil, err
×
1155
        }
×
1156

UNCOV
1157
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
×
1158
}
1159

1160
// ReceiverHtlcSpendTimeout constructs a valid witness allowing the sender of
1161
// an HTLC to recover the pending funds after an absolute timeout in the
1162
// scenario that the receiver of the HTLC broadcasts their version of the
1163
// commitment transaction. If the caller has already set the lock time on the
1164
// spending transaction, than a value of -1 can be passed for the cltvExpiry
1165
// value.
1166
//
1167
// NOTE: The target input of the passed transaction MUST NOT have a final
1168
// sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
1169
func ReceiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
1170
        sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) {
4✔
1171

4✔
1172
        // If the caller set a proper timeout value, then we'll apply it
4✔
1173
        // directly to the transaction.
4✔
1174
        if cltvExpiry != -1 {
4✔
UNCOV
1175
                // The HTLC output has an absolute time period before we are
×
UNCOV
1176
                // permitted to recover the pending funds. Therefore we need to
×
UNCOV
1177
                // set the locktime on this sweeping transaction in order to
×
UNCOV
1178
                // pass Script verification.
×
UNCOV
1179
                sweepTx.LockTime = uint32(cltvExpiry)
×
UNCOV
1180
        }
×
1181

1182
        // With the lock time on the transaction set, we'll not generate a
1183
        // signature for the sweep transaction. The passed sign descriptor
1184
        // should be created using the raw public key of the sender (w/o the
1185
        // single tweak applied), and the single tweak set to the proper value
1186
        // taking into account the current state's point.
1187
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1188
        if err != nil {
4✔
1189
                return nil, err
×
1190
        }
×
1191

1192
        witnessStack := wire.TxWitness(make([][]byte, 3))
4✔
1193
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
1194
        witnessStack[1] = nil
4✔
1195
        witnessStack[2] = signDesc.WitnessScript
4✔
1196

4✔
1197
        return witnessStack, nil
4✔
1198
}
1199

1200
// ReceiverHtlcTapLeafTimeout returns the full tapscript leaf for the timeout
1201
// path of the sender HTLC. This is a small script that allows the sender
1202
// timeout the HTLC after expiry:
1203
//
1204
//        <sender_htlcpubkey> OP_CHECKSIG
1205
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
1206
//        <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1207
func ReceiverHtlcTapLeafTimeout(senderHtlcKey *btcec.PublicKey,
1208
        cltvExpiry uint32) (txscript.TapLeaf, error) {
4✔
1209

4✔
1210
        builder := txscript.NewScriptBuilder()
4✔
1211

4✔
1212
        // The first part of the script will verify a signature from the
4✔
1213
        // sender authorizing the spend (the timeout).
4✔
1214
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
4✔
1215
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1216
        builder.AddOp(txscript.OP_1)
4✔
1217
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
1218
        builder.AddOp(txscript.OP_DROP)
4✔
1219

4✔
1220
        // The second portion will ensure that the CLTV expiry on the spending
4✔
1221
        // transaction is correct.
4✔
1222
        builder.AddInt64(int64(cltvExpiry))
4✔
1223
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
4✔
1224
        builder.AddOp(txscript.OP_DROP)
4✔
1225

4✔
1226
        timeoutLeafScript, err := builder.Script()
4✔
1227
        if err != nil {
4✔
1228
                return txscript.TapLeaf{}, err
×
1229
        }
×
1230

1231
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
4✔
1232
}
1233

1234
// ReceiverHtlcTapLeafSuccess returns the full tapscript leaf for the success
1235
// path for an HTLC on the receiver's commitment transaction. This script
1236
// allows the receiver to redeem an HTLC with knowledge of the preimage:
1237
//
1238
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
1239
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1240
//        <receiver_htlcpubkey> OP_CHECKSIGVERIFY
1241
//        <sender_htlcpubkey> OP_CHECKSIG
1242
func ReceiverHtlcTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
1243
        senderHtlcKey *btcec.PublicKey,
1244
        paymentHash []byte) (txscript.TapLeaf, error) {
4✔
1245

4✔
1246
        builder := txscript.NewScriptBuilder()
4✔
1247

4✔
1248
        // Check that the pre-image is 32 bytes as required.
4✔
1249
        builder.AddOp(txscript.OP_SIZE)
4✔
1250
        builder.AddInt64(32)
4✔
1251
        builder.AddOp(txscript.OP_EQUALVERIFY)
4✔
1252

4✔
1253
        // Check that the specified pre-image matches what we hard code into
4✔
1254
        // the script.
4✔
1255
        builder.AddOp(txscript.OP_HASH160)
4✔
1256
        builder.AddData(Ripemd160H(paymentHash))
4✔
1257
        builder.AddOp(txscript.OP_EQUALVERIFY)
4✔
1258

4✔
1259
        // Verify the "2-of-2" multi-sig that requires both parties to sign
4✔
1260
        // off.
4✔
1261
        builder.AddData(schnorr.SerializePubKey(receiverHtlcKey))
4✔
1262
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
4✔
1263
        builder.AddData(schnorr.SerializePubKey(senderHtlcKey))
4✔
1264
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1265

4✔
1266
        successLeafScript, err := builder.Script()
4✔
1267
        if err != nil {
4✔
1268
                return txscript.TapLeaf{}, err
×
1269
        }
×
1270

1271
        return txscript.NewBaseTapLeaf(successLeafScript), nil
4✔
1272
}
1273

1274
// receiverHtlcTapScriptTree builds the tapscript tree which is used to anchor
1275
// the HTLC key for HTLCs on the receiver's commitment.
1276
func receiverHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
1277
        revokeKey *btcec.PublicKey, payHash []byte,
1278
        cltvExpiry uint32, hType htlcType) (*HtlcScriptTree, error) {
4✔
1279

4✔
1280
        // First, we'll obtain the tap leaves for both the success and timeout
4✔
1281
        // path.
4✔
1282
        successTapLeaf, err := ReceiverHtlcTapLeafSuccess(
4✔
1283
                receiverHtlcKey, senderHtlcKey, payHash,
4✔
1284
        )
4✔
1285
        if err != nil {
4✔
1286
                return nil, err
×
1287
        }
×
1288
        timeoutTapLeaf, err := ReceiverHtlcTapLeafTimeout(
4✔
1289
                senderHtlcKey, cltvExpiry,
4✔
1290
        )
4✔
1291
        if err != nil {
4✔
1292
                return nil, err
×
1293
        }
×
1294

1295
        // With the two leaves obtained, we'll now make the tapscript tree,
1296
        // then obtain the root from that
1297
        tapscriptTree := txscript.AssembleTaprootScriptTree(
4✔
1298
                timeoutTapLeaf, successTapLeaf,
4✔
1299
        )
4✔
1300

4✔
1301
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
4✔
1302

4✔
1303
        // With the tapscript root obtained, we'll tweak the revocation key
4✔
1304
        // with this value to obtain the key that HTLCs will be sent to.
4✔
1305
        htlcKey := txscript.ComputeTaprootOutputKey(
4✔
1306
                revokeKey, tapScriptRoot[:],
4✔
1307
        )
4✔
1308

4✔
1309
        return &HtlcScriptTree{
4✔
1310
                ScriptTree: ScriptTree{
4✔
1311
                        TaprootKey:    htlcKey,
4✔
1312
                        TapscriptTree: tapscriptTree,
4✔
1313
                        TapscriptRoot: tapScriptRoot[:],
4✔
1314
                        InternalKey:   revokeKey,
4✔
1315
                },
4✔
1316
                SuccessTapLeaf: successTapLeaf,
4✔
1317
                TimeoutTapLeaf: timeoutTapLeaf,
4✔
1318
                htlcType:       hType,
4✔
1319
        }, nil
4✔
1320
}
1321

1322
// ReceiverHTLCScriptTaproot constructs the taproot witness program (schnor
1323
// key) for an incoming HTLC on the receiver's version of the commitment
1324
// transaction. This method returns the top level tweaked public key that
1325
// commits to both the script paths. From the PoV of the receiver, this is an
1326
// accepted HTLC.
1327
//
1328
// The returned key commits to a tapscript tree with two possible paths:
1329
//
1330
//   - The timeout path:
1331
//     <remote_htlcpubkey> OP_CHECKSIG
1332
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
1333
//     <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1334
//
1335
//   - Success path:
1336
//     OP_SIZE 32 OP_EQUALVERIFY
1337
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1338
//     <local_htlcpubkey> OP_CHECKSIGVERIFY
1339
//     <remote_htlcpubkey> OP_CHECKSIG
1340
//
1341
// The timeout path can be spent with a witness of:
1342
//   - <sender sig> <timeout_script> <control_block>
1343
//
1344
// The success path can be spent with a witness of:
1345
//   - <sender sig> <receiver sig> <preimage> <success_script> <control_block>
1346
//
1347
// The top level keyspend key is the revocation key, which allows a defender to
1348
// unilaterally spend the created output. Both the final output key as well as
1349
// the tap leaf are returned.
1350
func ReceiverHTLCScriptTaproot(cltvExpiry uint32,
1351
        senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey,
1352
        payHash []byte, whoseCommit lntypes.ChannelParty,
1353
) (*HtlcScriptTree, error) {
4✔
1354

4✔
1355
        var hType htlcType
4✔
1356
        if whoseCommit.IsLocal() {
8✔
1357
                hType = htlcLocalIncoming
4✔
1358
        } else {
8✔
1359
                hType = htlcRemoteOutgoing
4✔
1360
        }
4✔
1361

1362
        // Given all the necessary parameters, we'll return the HTLC script
1363
        // tree that includes the top level output script, as well as the two
1364
        // tap leaf paths.
1365
        return receiverHtlcTapScriptTree(
4✔
1366
                senderHtlcKey, receiverHtlcKey, revocationKey, payHash,
4✔
1367
                cltvExpiry, hType,
4✔
1368
        )
4✔
1369
}
1370

1371
// ReceiverHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
1372
// receiver taproot HTLC with the pre-image. The returned witness is valid and
1373
// includes the control block required to spend the output.
1374
func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
1375
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1376
        signer Signer, signDesc *SignDescriptor,
1377
        htlcSuccessTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1378
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
1379

4✔
1380
        // First, we'll generate a signature for the HTLC success transaction.
4✔
1381
        // The signDesc should be signing with the public key used as the
4✔
1382
        // receiver's public key and also the correct single tweak.
4✔
1383
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
4✔
1384
        if err != nil {
4✔
1385
                return nil, err
×
1386
        }
×
1387

1388
        // In addition to the signature and the witness/leaf script, we also
1389
        // need to make a control block proof using the tapscript tree.
1390
        var ctrlBlock []byte
4✔
1391
        if signDesc.ControlBlock == nil {
8✔
1392
                redeemControlBlock := MakeTaprootCtrlBlock(
4✔
1393
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
4✔
1394
                )
4✔
1395
                ctrlBytes, err := redeemControlBlock.ToBytes()
4✔
1396
                if err != nil {
4✔
1397
                        return nil, err
×
1398
                }
×
1399

1400
                ctrlBlock = ctrlBytes
4✔
1401
        } else {
4✔
1402
                ctrlBlock = signDesc.ControlBlock
4✔
1403
        }
4✔
1404

1405
        // The final witness stack is:
1406
        //  * <sender sig> <receiver sig> <preimage> <success_script>
1407
        //    <control_block>
1408
        witnessStack := wire.TxWitness(make([][]byte, 5))
4✔
1409
        witnessStack[0] = maybeAppendSighash(senderSig, senderSigHash)
4✔
1410
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
1411
        witnessStack[2] = paymentPreimage
4✔
1412
        witnessStack[3] = signDesc.WitnessScript
4✔
1413
        witnessStack[4] = ctrlBlock
4✔
1414

4✔
1415
        return witnessStack, nil
4✔
1416
}
1417

1418
// ReceiverHTLCScriptTaprootTimeout creates a valid witness needed to timeout
1419
// an HTLC on the receiver's commitment transaction after the timeout has
1420
// elapsed.
1421
func ReceiverHTLCScriptTaprootTimeout(signer Signer, signDesc *SignDescriptor,
1422
        sweepTx *wire.MsgTx, cltvExpiry int32, revokeKey *btcec.PublicKey,
1423
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
1424

4✔
1425
        // If the caller set a proper timeout value, then we'll apply it
4✔
1426
        // directly to the transaction.
4✔
1427
        //
4✔
1428
        // TODO(roasbeef): helper func
4✔
1429
        if cltvExpiry != -1 {
4✔
UNCOV
1430
                // The HTLC output has an absolute time period before we are
×
UNCOV
1431
                // permitted to recover the pending funds. Therefore we need to
×
UNCOV
1432
                // set the locktime on this sweeping transaction in order to
×
UNCOV
1433
                // pass Script verification.
×
UNCOV
1434
                sweepTx.LockTime = uint32(cltvExpiry)
×
UNCOV
1435
        }
×
1436

1437
        // With the lock time on the transaction set, we'll now generate a
1438
        // signature for the sweep transaction. The passed sign descriptor
1439
        // should be created using the raw public key of the sender (w/o the
1440
        // single tweak applied), and the single tweak set to the proper value
1441
        // taking into account the current state's point.
1442
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1443
        if err != nil {
4✔
1444
                return nil, err
×
1445
        }
×
1446

1447
        // In addition to the signature and the witness/leaf script, we also
1448
        // need to make a control block proof using the tapscript tree.
1449
        var ctrlBlock []byte
4✔
1450
        if signDesc.ControlBlock == nil {
4✔
UNCOV
1451
                timeoutControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
1452
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
1453
                )
×
UNCOV
1454
                ctrlBlock, err = timeoutControlBlock.ToBytes()
×
UNCOV
1455
                if err != nil {
×
1456
                        return nil, err
×
1457
                }
×
1458
        } else {
4✔
1459
                ctrlBlock = signDesc.ControlBlock
4✔
1460
        }
4✔
1461

1462
        // The final witness is pretty simple, we just need to present a valid
1463
        // signature for the script, and then provide the control block.
1464
        witnessStack := make(wire.TxWitness, 3)
4✔
1465
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
1466
        witnessStack[1] = signDesc.WitnessScript
4✔
1467
        witnessStack[2] = ctrlBlock
4✔
1468

4✔
1469
        return witnessStack, nil
4✔
1470
}
1471

1472
// ReceiverHTLCScriptTaprootRevoke creates a valid witness needed to spend the
1473
// revocation path of the HTLC from the PoV of the sender (offerer) of the
1474
// HTLC. This uses a plain keyspend using the specified revocation key.
1475
func ReceiverHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
1476
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
1477

4✔
1478
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1479
        if err != nil {
4✔
1480
                return nil, err
×
1481
        }
×
1482

1483
        // The witness stack in this case is pretty simple: we only need to
1484
        // specify the signature generated.
1485
        witnessStack := make(wire.TxWitness, 1)
4✔
1486
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
1487

4✔
1488
        return witnessStack, nil
4✔
1489
}
1490

1491
// SecondLevelHtlcScript is the uniform script that's used as the output for
1492
// the second-level HTLC transactions. The second level transaction act as a
1493
// sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1494
// spent in a particular way, and to a particular output.
1495
//
1496
// Possible Input Scripts:
1497
//
1498
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1499
//     state:
1500
//     <revoke sig> 1
1501
//
1502
//   - To claim and HTLC output, either with a pre-image or due to a timeout:
1503
//     <delay sig> 0
1504
//
1505
// Output Script:
1506
//
1507
//         OP_IF
1508
//                <revoke key>
1509
//         OP_ELSE
1510
//                <delay in blocks>
1511
//                OP_CHECKSEQUENCEVERIFY
1512
//                OP_DROP
1513
//                <delay key>
1514
//         OP_ENDIF
1515
//         OP_CHECKSIG
1516
//
1517
// TODO(roasbeef): possible renames for second-level
1518
//   - transition?
1519
//   - covenant output
1520
func SecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1521
        csvDelay uint32) ([]byte, error) {
4✔
1522

4✔
1523
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
1524
                ToLocalScriptSize,
4✔
1525
        ))
4✔
1526

4✔
1527
        // If this is the revocation clause for this script is to be executed,
4✔
1528
        // the spender will push a 1, forcing us to hit the true clause of this
4✔
1529
        // if statement.
4✔
1530
        builder.AddOp(txscript.OP_IF)
4✔
1531

4✔
1532
        // If this is the revocation case, then we'll push the revocation
4✔
1533
        // public key on the stack.
4✔
1534
        builder.AddData(revocationKey.SerializeCompressed())
4✔
1535

4✔
1536
        // Otherwise, this is either the sender or receiver of the HTLC
4✔
1537
        // attempting to claim the HTLC output.
4✔
1538
        builder.AddOp(txscript.OP_ELSE)
4✔
1539

4✔
1540
        // In order to give the other party time to execute the revocation
4✔
1541
        // clause above, we require a relative timeout to pass before the
4✔
1542
        // output can be spent.
4✔
1543
        builder.AddInt64(int64(csvDelay))
4✔
1544
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
1545
        builder.AddOp(txscript.OP_DROP)
4✔
1546

4✔
1547
        // If the relative timelock passes, then we'll add the delay key to the
4✔
1548
        // stack to ensure that we properly authenticate the spending party.
4✔
1549
        builder.AddData(delayKey.SerializeCompressed())
4✔
1550

4✔
1551
        // Close out the if statement.
4✔
1552
        builder.AddOp(txscript.OP_ENDIF)
4✔
1553

4✔
1554
        // In either case, we'll ensure that only either the party possessing
4✔
1555
        // the revocation private key, or the delay private key is able to
4✔
1556
        // spend this output.
4✔
1557
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1558

4✔
1559
        return builder.Script()
4✔
1560
}
4✔
1561

1562
// TODO(roasbeef): move all taproot stuff to new file?
1563

1564
// TaprootSecondLevelTapLeaf constructs the tap leaf used as the sole script
1565
// path for a second level HTLC spend.
1566
//
1567
// The final script used is:
1568
//
1569
//        <local_delay_key> OP_CHECKSIG
1570
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1571
func TaprootSecondLevelTapLeaf(delayKey *btcec.PublicKey,
1572
        csvDelay uint32) (txscript.TapLeaf, error) {
4✔
1573

4✔
1574
        builder := txscript.NewScriptBuilder()
4✔
1575

4✔
1576
        // Ensure the proper party can sign for this output.
4✔
1577
        builder.AddData(schnorr.SerializePubKey(delayKey))
4✔
1578
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1579

4✔
1580
        // Assuming the above passes, then we'll now ensure that the CSV delay
4✔
1581
        // has been upheld, dropping the int we pushed on. If the sig above is
4✔
1582
        // valid, then a 1 will be left on the stack.
4✔
1583
        builder.AddInt64(int64(csvDelay))
4✔
1584
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
1585
        builder.AddOp(txscript.OP_DROP)
4✔
1586

4✔
1587
        secondLevelLeafScript, err := builder.Script()
4✔
1588
        if err != nil {
4✔
1589
                return txscript.TapLeaf{}, err
×
1590
        }
×
1591

1592
        return txscript.NewBaseTapLeaf(secondLevelLeafScript), nil
4✔
1593
}
1594

1595
// SecondLevelHtlcTapscriptTree construct the indexed tapscript tree needed to
1596
// generate the taptweak to create the final output and also control block.
1597
func SecondLevelHtlcTapscriptTree(delayKey *btcec.PublicKey,
1598
        csvDelay uint32) (*txscript.IndexedTapScriptTree, error) {
4✔
1599

4✔
1600
        // First grab the second level leaf script we need to create the top
4✔
1601
        // level output.
4✔
1602
        secondLevelTapLeaf, err := TaprootSecondLevelTapLeaf(delayKey, csvDelay)
4✔
1603
        if err != nil {
4✔
1604
                return nil, err
×
1605
        }
×
1606

1607
        // Now that we have the sole second level script, we can create the
1608
        // tapscript tree that commits to both the leaves.
1609
        return txscript.AssembleTaprootScriptTree(secondLevelTapLeaf), nil
4✔
1610
}
1611

1612
// TaprootSecondLevelHtlcScript is the uniform script that's used as the output
1613
// for the second-level HTLC transaction. The second level transaction acts as
1614
// an off-chain 2-of-2 covenant that can only be spent a particular way and to
1615
// a particular output.
1616
//
1617
// Possible Input Scripts:
1618
//   - revocation sig
1619
//   - <local_delay_sig>
1620
//
1621
// The script main script lets the broadcaster spend after a delay the script
1622
// path:
1623
//
1624
//        <local_delay_key> OP_CHECKSIG
1625
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1626
//
1627
// The keyspend path require knowledge of the top level revocation private key.
1628
func TaprootSecondLevelHtlcScript(revokeKey, delayKey *btcec.PublicKey,
1629
        csvDelay uint32) (*btcec.PublicKey, error) {
×
1630

×
1631
        // First, we'll make the tapscript tree that commits to the redemption
×
1632
        // path.
×
1633
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
×
1634
                delayKey, csvDelay,
×
1635
        )
×
1636
        if err != nil {
×
1637
                return nil, err
×
1638
        }
×
1639

1640
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
×
1641

×
1642
        // With the tapscript root obtained, we'll tweak the revocation key
×
1643
        // with this value to obtain the key that the second level spend will
×
1644
        // create.
×
1645
        redemptionKey := txscript.ComputeTaprootOutputKey(
×
1646
                revokeKey, tapScriptRoot[:],
×
1647
        )
×
1648

×
1649
        return redemptionKey, nil
×
1650
}
1651

1652
// SecondLevelScriptTree is a tapscript tree used to spend the second level
1653
// HTLC output after the CSV delay has passed.
1654
type SecondLevelScriptTree struct {
1655
        ScriptTree
1656

1657
        // SuccessTapLeaf is the tapleaf for the redemption path.
1658
        SuccessTapLeaf txscript.TapLeaf
1659
}
1660

1661
// TaprootSecondLevelScriptTree constructs the tapscript tree used to spend the
1662
// second level HTLC output.
1663
func TaprootSecondLevelScriptTree(revokeKey, delayKey *btcec.PublicKey,
1664
        csvDelay uint32) (*SecondLevelScriptTree, error) {
4✔
1665

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

1675
        // With the tree constructed, we can make the pkscript which is the
1676
        // taproot output key itself.
1677
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
4✔
1678
        outputKey := txscript.ComputeTaprootOutputKey(
4✔
1679
                revokeKey, tapScriptRoot[:],
4✔
1680
        )
4✔
1681

4✔
1682
        return &SecondLevelScriptTree{
4✔
1683
                ScriptTree: ScriptTree{
4✔
1684
                        TaprootKey:    outputKey,
4✔
1685
                        TapscriptTree: tapScriptTree,
4✔
1686
                        TapscriptRoot: tapScriptRoot[:],
4✔
1687
                        InternalKey:   revokeKey,
4✔
1688
                },
4✔
1689
                SuccessTapLeaf: tapScriptTree.LeafMerkleProofs[0].TapLeaf,
4✔
1690
        }, nil
4✔
1691
}
1692

1693
// WitnessScript returns the witness script that we'll use when signing for the
1694
// remote party, and also verifying signatures on our transactions. As an
1695
// example, when we create an outgoing HTLC for the remote party, we want to
1696
// sign their success path.
1697
func (s *SecondLevelScriptTree) WitnessScriptToSign() []byte {
×
1698
        return s.SuccessTapLeaf.Script
×
1699
}
×
1700

1701
// WitnessScriptForPath returns the witness script for the given spending path.
1702
// An error is returned if the path is unknown.
1703
func (s *SecondLevelScriptTree) WitnessScriptForPath(path ScriptPath,
1704
) ([]byte, error) {
4✔
1705

4✔
1706
        switch path {
4✔
1707
        case ScriptPathDelay:
×
1708
                fallthrough
×
1709
        case ScriptPathSuccess:
4✔
1710
                return s.SuccessTapLeaf.Script, nil
4✔
1711

1712
        default:
×
1713
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1714
        }
1715
}
1716

1717
// CtrlBlockForPath returns the control block for the given spending path. For
1718
// script types that don't have a control block, nil is returned.
1719
func (s *SecondLevelScriptTree) CtrlBlockForPath(path ScriptPath,
1720
) (*txscript.ControlBlock, error) {
4✔
1721

4✔
1722
        switch path {
4✔
1723
        case ScriptPathDelay:
×
1724
                fallthrough
×
1725
        case ScriptPathSuccess:
4✔
1726
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
1727
                        s.SuccessTapLeaf.Script, s.InternalKey,
4✔
1728
                        s.TapscriptTree,
4✔
1729
                )), nil
4✔
1730

1731
        default:
×
1732
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1733
        }
1734
}
1735

1736
// A compile time check to ensure SecondLevelScriptTree implements the
1737
// TapscriptDescriptor interface.
1738
var _ TapscriptDescriptor = (*SecondLevelScriptTree)(nil)
1739

1740
// TaprootHtlcSpendRevoke spends a second-level HTLC output via the revocation
1741
// path. This uses the top level keyspend path to redeem the contested output.
1742
//
1743
// The passed SignDescriptor MUST have the proper witness script and also the
1744
// proper top-level tweak derived from the tapscript tree for the second level
1745
// output.
1746
func TaprootHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1747
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1748

×
UNCOV
1749
        // We don't need any spacial modifications to the transaction as this
×
UNCOV
1750
        // is just sweeping a revoked HTLC output. So we'll generate a regular
×
UNCOV
1751
        // schnorr signature.
×
UNCOV
1752
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
×
UNCOV
1753
        if err != nil {
×
1754
                return nil, err
×
1755
        }
×
1756

1757
        // The witness stack in this case is pretty simple: we only need to
1758
        // specify the signature generated.
UNCOV
1759
        witnessStack := make(wire.TxWitness, 1)
×
UNCOV
1760
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
×
UNCOV
1761

×
UNCOV
1762
        return witnessStack, nil
×
1763
}
1764

1765
// TaprootHtlcSpendSuccess spends a second-level HTLC output via the redemption
1766
// path. This should be used to sweep funds after the pre-image is known.
1767
//
1768
// NOTE: The caller MUST set the txn version, sequence number, and sign
1769
// descriptor's sig hash cache before invocation.
1770
func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
1771
        sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1772
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
1773

4✔
1774
        // First, we'll generate the sweep signature based on the populated
4✔
1775
        // sign desc. This should give us a valid schnorr signature for the
4✔
1776
        // sole script path leaf.
4✔
1777
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1778
        if err != nil {
4✔
1779
                return nil, err
×
1780
        }
×
1781

1782
        var ctrlBlock []byte
4✔
1783
        if signDesc.ControlBlock == nil {
4✔
UNCOV
1784
                // Now that we have the sweep signature, we'll construct the
×
UNCOV
1785
                // control block needed to spend the script path.
×
UNCOV
1786
                redeemControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
1787
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
×
UNCOV
1788
                )
×
UNCOV
1789

×
UNCOV
1790
                ctrlBlock, err = redeemControlBlock.ToBytes()
×
UNCOV
1791
                if err != nil {
×
1792
                        return nil, err
×
1793
                }
×
1794
        } else {
4✔
1795
                ctrlBlock = signDesc.ControlBlock
4✔
1796
        }
4✔
1797

1798
        // Now that we have the redeem control block, we can construct the
1799
        // final witness needed to spend the script:
1800
        //
1801
        //  <success sig> <success script> <control_block>
1802
        witnessStack := make(wire.TxWitness, 3)
4✔
1803
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
1804
        witnessStack[1] = signDesc.WitnessScript
4✔
1805
        witnessStack[2] = ctrlBlock
4✔
1806

4✔
1807
        return witnessStack, nil
4✔
1808
}
1809

1810
// LeaseSecondLevelHtlcScript is the uniform script that's used as the output
1811
// for the second-level HTLC transactions. The second level transaction acts as
1812
// a sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1813
// spent in a particular way, and to a particular output.
1814
//
1815
// Possible Input Scripts:
1816
//
1817
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1818
//     state:
1819
//     <revoke sig> 1
1820
//
1821
//   - To claim an HTLC output, either with a pre-image or due to a timeout:
1822
//     <delay sig> 0
1823
//
1824
// Output Script:
1825
//
1826
//         OP_IF
1827
//                <revoke key>
1828
//         OP_ELSE
1829
//                <lease maturity in blocks>
1830
//                OP_CHECKLOCKTIMEVERIFY
1831
//                OP_DROP
1832
//                <delay in blocks>
1833
//                OP_CHECKSEQUENCEVERIFY
1834
//                OP_DROP
1835
//                <delay key>
1836
//         OP_ENDIF
1837
//         OP_CHECKSIG.
1838
func LeaseSecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1839
        csvDelay, cltvExpiry uint32) ([]byte, error) {
4✔
1840

4✔
1841
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
1842
                ToLocalScriptSize + LeaseWitnessScriptSizeOverhead,
4✔
1843
        ))
4✔
1844

4✔
1845
        // If this is the revocation clause for this script is to be executed,
4✔
1846
        // the spender will push a 1, forcing us to hit the true clause of this
4✔
1847
        // if statement.
4✔
1848
        builder.AddOp(txscript.OP_IF)
4✔
1849

4✔
1850
        // If this this is the revocation case, then we'll push the revocation
4✔
1851
        // public key on the stack.
4✔
1852
        builder.AddData(revocationKey.SerializeCompressed())
4✔
1853

4✔
1854
        // Otherwise, this is either the sender or receiver of the HTLC
4✔
1855
        // attempting to claim the HTLC output.
4✔
1856
        builder.AddOp(txscript.OP_ELSE)
4✔
1857

4✔
1858
        // The channel initiator always has the additional channel lease
4✔
1859
        // expiration constraint for outputs that pay to them which must be
4✔
1860
        // satisfied.
4✔
1861
        builder.AddInt64(int64(cltvExpiry))
4✔
1862
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
4✔
1863
        builder.AddOp(txscript.OP_DROP)
4✔
1864

4✔
1865
        // In order to give the other party time to execute the revocation
4✔
1866
        // clause above, we require a relative timeout to pass before the
4✔
1867
        // output can be spent.
4✔
1868
        builder.AddInt64(int64(csvDelay))
4✔
1869
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
1870
        builder.AddOp(txscript.OP_DROP)
4✔
1871

4✔
1872
        // If the relative timelock passes, then we'll add the delay key to the
4✔
1873
        // stack to ensure that we properly authenticate the spending party.
4✔
1874
        builder.AddData(delayKey.SerializeCompressed())
4✔
1875

4✔
1876
        // Close out the if statement.
4✔
1877
        builder.AddOp(txscript.OP_ENDIF)
4✔
1878

4✔
1879
        // In either case, we'll ensure that only either the party possessing
4✔
1880
        // the revocation private key, or the delay private key is able to
4✔
1881
        // spend this output.
4✔
1882
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
1883

4✔
1884
        return builder.Script()
4✔
1885
}
4✔
1886

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

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

×
UNCOV
1898
        // Finally, OP_CSV requires that the version of the transaction
×
UNCOV
1899
        // spending a pkscript with OP_CSV within it *must* be >= 2.
×
UNCOV
1900
        sweepTx.Version = 2
×
UNCOV
1901

×
UNCOV
1902
        // As we mutated the transaction, we'll re-calculate the sighashes for
×
UNCOV
1903
        // this instance.
×
UNCOV
1904
        signDesc.SigHashes = NewTxSigHashesV0Only(sweepTx)
×
UNCOV
1905

×
UNCOV
1906
        // With the proper sequence and version set, we'll now sign the timeout
×
UNCOV
1907
        // transaction using the passed signed descriptor. In order to generate
×
UNCOV
1908
        // a valid signature, then signDesc should be using the base delay
×
UNCOV
1909
        // public key, and the proper single tweak bytes.
×
UNCOV
1910
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
×
UNCOV
1911
        if err != nil {
×
1912
                return nil, err
×
1913
        }
×
1914

1915
        // We set a zero as the first element the witness stack (ignoring the
1916
        // witness script), in order to force execution to the second portion
1917
        // of the if clause.
UNCOV
1918
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1919
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1920
        witnessStack[1] = nil
×
UNCOV
1921
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1922

×
UNCOV
1923
        return witnessStack, nil
×
1924
}
1925

1926
// HtlcSpendRevoke spends a second-level HTLC output. This function is to be
1927
// used by the sender or receiver of an HTLC to claim the HTLC after a revoked
1928
// commitment transaction was broadcast.
1929
func HtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
UNCOV
1930
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
×
UNCOV
1931

×
UNCOV
1932
        // We don't need any spacial modifications to the transaction as this
×
UNCOV
1933
        // is just sweeping a revoked HTLC output. So we'll generate a regular
×
UNCOV
1934
        // witness signature.
×
UNCOV
1935
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
×
UNCOV
1936
        if err != nil {
×
1937
                return nil, err
×
1938
        }
×
1939

1940
        // We set a one as the first element the witness stack (ignoring the
1941
        // witness script), in order to force execution to the revocation
1942
        // clause in the second level HTLC script.
UNCOV
1943
        witnessStack := wire.TxWitness(make([][]byte, 3))
×
UNCOV
1944
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
×
UNCOV
1945
        witnessStack[1] = []byte{1}
×
UNCOV
1946
        witnessStack[2] = signDesc.WitnessScript
×
UNCOV
1947

×
UNCOV
1948
        return witnessStack, nil
×
1949
}
1950

1951
// HtlcSecondLevelSpend exposes the public witness generation function for
1952
// spending an HTLC success transaction, either due to an expiring time lock or
1953
// having had the payment preimage. This method is able to spend any
1954
// second-level HTLC transaction, assuming the caller sets the locktime or
1955
// seqno properly.
1956
//
1957
// NOTE: The caller MUST set the txn version, sequence number, and sign
1958
// descriptor's sig hash cache before invocation.
1959
func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor,
1960
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
1961

4✔
1962
        // With the proper sequence and version set, we'll now sign the timeout
4✔
1963
        // transaction using the passed signed descriptor. In order to generate
4✔
1964
        // a valid signature, then signDesc should be using the base delay
4✔
1965
        // public key, and the proper single tweak bytes.
4✔
1966
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1967
        if err != nil {
4✔
1968
                return nil, err
×
1969
        }
×
1970

1971
        // We set a zero as the first element the witness stack (ignoring the
1972
        // witness script), in order to force execution to the second portion
1973
        // of the if clause.
1974
        witnessStack := wire.TxWitness(make([][]byte, 3))
4✔
1975
        witnessStack[0] = append(sweepSig.Serialize(), byte(txscript.SigHashAll))
4✔
1976
        witnessStack[1] = nil
4✔
1977
        witnessStack[2] = signDesc.WitnessScript
4✔
1978

4✔
1979
        return witnessStack, nil
4✔
1980
}
1981

1982
// LockTimeToSequence converts the passed relative locktime to a sequence
1983
// number in accordance to BIP-68.
1984
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
1985
//   - (Compatibility)
UNCOV
1986
func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
×
UNCOV
1987
        if !isSeconds {
×
UNCOV
1988
                // The locktime is to be expressed in confirmations.
×
UNCOV
1989
                return locktime
×
UNCOV
1990
        }
×
1991

1992
        // Set the 22nd bit which indicates the lock time is in seconds, then
1993
        // shift the locktime over by 9 since the time granularity is in
1994
        // 512-second intervals (2^9). This results in a max lock-time of
1995
        // 33,554,431 seconds, or 1.06 years.
1996
        return SequenceLockTimeSeconds | (locktime >> 9)
×
1997
}
1998

1999
// CommitScriptToSelf constructs the public key script for the output on the
2000
// commitment transaction paying to the "owner" of said commitment transaction.
2001
// If the other party learns of the preimage to the revocation hash, then they
2002
// can claim all the settled funds in the channel, plus the unsettled funds.
2003
//
2004
// Possible Input Scripts:
2005
//
2006
//        REVOKE:     <sig> 1
2007
//        SENDRSWEEP: <sig> <emptyvector>
2008
//
2009
// Output Script:
2010
//
2011
//        OP_IF
2012
//            <revokeKey>
2013
//        OP_ELSE
2014
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
2015
//            <selfKey>
2016
//        OP_ENDIF
2017
//        OP_CHECKSIG
2018
func CommitScriptToSelf(csvTimeout uint32, selfKey, revokeKey *btcec.PublicKey) ([]byte, error) {
4✔
2019
        // This script is spendable under two conditions: either the
4✔
2020
        // 'csvTimeout' has passed and we can redeem our funds, or they can
4✔
2021
        // produce a valid signature with the revocation public key. The
4✔
2022
        // revocation public key will *only* be known to the other party if we
4✔
2023
        // have divulged the revocation hash, allowing them to homomorphically
4✔
2024
        // derive the proper private key which corresponds to the revoke public
4✔
2025
        // key.
4✔
2026
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
2027
                ToLocalScriptSize,
4✔
2028
        ))
4✔
2029

4✔
2030
        builder.AddOp(txscript.OP_IF)
4✔
2031

4✔
2032
        // If a valid signature using the revocation key is presented, then
4✔
2033
        // allow an immediate spend provided the proper signature.
4✔
2034
        builder.AddData(revokeKey.SerializeCompressed())
4✔
2035

4✔
2036
        builder.AddOp(txscript.OP_ELSE)
4✔
2037

4✔
2038
        // Otherwise, we can re-claim our funds after a CSV delay of
4✔
2039
        // 'csvTimeout' timeout blocks, and a valid signature.
4✔
2040
        builder.AddInt64(int64(csvTimeout))
4✔
2041
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2042
        builder.AddOp(txscript.OP_DROP)
4✔
2043
        builder.AddData(selfKey.SerializeCompressed())
4✔
2044

4✔
2045
        builder.AddOp(txscript.OP_ENDIF)
4✔
2046

4✔
2047
        // Finally, we'll validate the signature against the public key that's
4✔
2048
        // left on the top of the stack.
4✔
2049
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2050

4✔
2051
        return builder.Script()
4✔
2052
}
4✔
2053

2054
// CommitScriptTree holds the taproot output key (in this case the revocation
2055
// key, or a NUMs point for the remote output) along with the tapscript leaf
2056
// that can spend the output after a delay.
2057
type CommitScriptTree struct {
2058
        ScriptTree
2059

2060
        // SettleLeaf is the leaf used to settle the output after the delay.
2061
        SettleLeaf txscript.TapLeaf
2062

2063
        // RevocationLeaf is the leaf used to spend the output with the
2064
        // revocation key signature.
2065
        RevocationLeaf txscript.TapLeaf
2066
}
2067

2068
// A compile time check to ensure CommitScriptTree implements the
2069
// TapscriptDescriptor interface.
2070
var _ TapscriptDescriptor = (*CommitScriptTree)(nil)
2071

2072
// WitnessScript returns the witness script that we'll use when signing for the
2073
// remote party, and also verifying signatures on our transactions. As an
2074
// example, when we create an outgoing HTLC for the remote party, we want to
2075
// sign their success path.
2076
func (c *CommitScriptTree) WitnessScriptToSign() []byte {
×
2077
        // TODO(roasbeef): abstraction leak here? always dependent
×
2078
        return nil
×
2079
}
×
2080

2081
// WitnessScriptForPath returns the witness script for the given spending path.
2082
// An error is returned if the path is unknown.
2083
func (c *CommitScriptTree) WitnessScriptForPath(path ScriptPath,
2084
) ([]byte, error) {
4✔
2085

4✔
2086
        switch path {
4✔
2087
        // For the commitment output, the delay and success path are the same,
2088
        // so we'll fall through here to success.
2089
        case ScriptPathDelay:
4✔
2090
                fallthrough
4✔
2091
        case ScriptPathSuccess:
4✔
2092
                return c.SettleLeaf.Script, nil
4✔
2093
        case ScriptPathRevocation:
4✔
2094
                return c.RevocationLeaf.Script, nil
4✔
2095
        default:
×
2096
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2097
        }
2098
}
2099

2100
// CtrlBlockForPath returns the control block for the given spending path. For
2101
// script types that don't have a control block, nil is returned.
2102
func (c *CommitScriptTree) CtrlBlockForPath(path ScriptPath,
2103
) (*txscript.ControlBlock, error) {
4✔
2104

4✔
2105
        switch path {
4✔
2106
        case ScriptPathDelay:
4✔
2107
                fallthrough
4✔
2108
        case ScriptPathSuccess:
4✔
2109
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
2110
                        c.SettleLeaf.Script, c.InternalKey,
4✔
2111
                        c.TapscriptTree,
4✔
2112
                )), nil
4✔
2113
        case ScriptPathRevocation:
4✔
2114
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
2115
                        c.RevocationLeaf.Script, c.InternalKey,
4✔
2116
                        c.TapscriptTree,
4✔
2117
                )), nil
4✔
2118
        default:
×
2119
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2120
        }
2121
}
2122

2123
// NewLocalCommitScriptTree returns a new CommitScript tree that can be used to
2124
// create and spend the commitment output for the local party.
2125
func NewLocalCommitScriptTree(csvTimeout uint32,
2126
        selfKey, revokeKey *btcec.PublicKey) (*CommitScriptTree, error) {
4✔
2127

4✔
2128
        // First, we'll need to construct the tapLeaf that'll be our delay CSV
4✔
2129
        // clause.
4✔
2130
        delayScript, err := TaprootLocalCommitDelayScript(csvTimeout, selfKey)
4✔
2131
        if err != nil {
4✔
2132
                return nil, err
×
2133
        }
×
2134

2135
        // Next, we'll need to construct the revocation path, which is just a
2136
        // simple checksig script.
2137
        revokeScript, err := TaprootLocalCommitRevokeScript(selfKey, revokeKey)
4✔
2138
        if err != nil {
4✔
2139
                return nil, err
×
2140
        }
×
2141

2142
        // With both scripts computed, we'll now create a tapscript tree with
2143
        // the two leaves, and then obtain a root from that.
2144
        delayTapLeaf := txscript.NewBaseTapLeaf(delayScript)
4✔
2145
        revokeTapLeaf := txscript.NewBaseTapLeaf(revokeScript)
4✔
2146
        tapScriptTree := txscript.AssembleTaprootScriptTree(
4✔
2147
                delayTapLeaf, revokeTapLeaf,
4✔
2148
        )
4✔
2149
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
4✔
2150

4✔
2151
        // Now that we have our root, we can arrive at the final output script
4✔
2152
        // by tweaking the internal key with this root.
4✔
2153
        toLocalOutputKey := txscript.ComputeTaprootOutputKey(
4✔
2154
                &TaprootNUMSKey, tapScriptRoot[:],
4✔
2155
        )
4✔
2156

4✔
2157
        return &CommitScriptTree{
4✔
2158
                ScriptTree: ScriptTree{
4✔
2159
                        TaprootKey:    toLocalOutputKey,
4✔
2160
                        TapscriptTree: tapScriptTree,
4✔
2161
                        TapscriptRoot: tapScriptRoot[:],
4✔
2162
                        InternalKey:   &TaprootNUMSKey,
4✔
2163
                },
4✔
2164
                SettleLeaf:     delayTapLeaf,
4✔
2165
                RevocationLeaf: revokeTapLeaf,
4✔
2166
        }, nil
4✔
2167
}
2168

2169
// TaprootLocalCommitDelayScript builds the tap leaf with the CSV delay script
2170
// for the to-local output.
2171
func TaprootLocalCommitDelayScript(csvTimeout uint32,
2172
        selfKey *btcec.PublicKey) ([]byte, error) {
4✔
2173

4✔
2174
        builder := txscript.NewScriptBuilder()
4✔
2175
        builder.AddData(schnorr.SerializePubKey(selfKey))
4✔
2176
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2177
        builder.AddInt64(int64(csvTimeout))
4✔
2178
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2179
        builder.AddOp(txscript.OP_DROP)
4✔
2180

4✔
2181
        return builder.Script()
4✔
2182
}
4✔
2183

2184
// TaprootLocalCommitRevokeScript builds the tap leaf with the revocation path
2185
// for the to-local output.
2186
func TaprootLocalCommitRevokeScript(selfKey, revokeKey *btcec.PublicKey) (
2187
        []byte, error) {
4✔
2188

4✔
2189
        builder := txscript.NewScriptBuilder()
4✔
2190
        builder.AddData(schnorr.SerializePubKey(selfKey))
4✔
2191
        builder.AddOp(txscript.OP_DROP)
4✔
2192
        builder.AddData(schnorr.SerializePubKey(revokeKey))
4✔
2193
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2194

4✔
2195
        return builder.Script()
4✔
2196
}
4✔
2197

2198
// TaprootCommitScriptToSelf creates the taproot witness program that commits
2199
// to the revocation (script path) and delay path (script path) in a single
2200
// taproot output key. Both the delay script and the revocation script are part
2201
// of the tapscript tree to ensure that the internal key (the local delay key)
2202
// is always revealed.  This ensures that a 3rd party can always sweep the set
2203
// of anchor outputs.
2204
//
2205
// For the delay path we have the following tapscript leaf script:
2206
//
2207
//        <local_delayedpubkey> OP_CHECKSIG
2208
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
2209
//
2210
// This can then be spent with just:
2211
//
2212
//        <local_delayedsig> <to_delay_script> <delay_control_block>
2213
//
2214
// Where the to_delay_script is listed above, and the delay_control_block
2215
// computed as:
2216
//
2217
//        delay_control_block = (output_key_y_parity | 0xc0) || taproot_nums_key
2218
//
2219
// The revocation path is simply:
2220
//
2221
//        <local_delayedpubkey> OP_DROP
2222
//        <revocationkey> OP_CHECKSIG
2223
//
2224
// The revocation path can be spent with a control block similar to the above
2225
// (but contains the hash of the other script), and with the following witness:
2226
//
2227
//        <revocation_sig>
2228
//
2229
// We use a noop data push to ensure that the local public key is also revealed
2230
// on chain, which enables the anchor output to be swept.
2231
func TaprootCommitScriptToSelf(csvTimeout uint32,
2232
        selfKey, revokeKey *btcec.PublicKey) (*btcec.PublicKey, error) {
×
2233

×
2234
        commitScriptTree, err := NewLocalCommitScriptTree(
×
2235
                csvTimeout, selfKey, revokeKey,
×
2236
        )
×
2237
        if err != nil {
×
2238
                return nil, err
×
2239
        }
×
2240

2241
        return commitScriptTree.TaprootKey, nil
×
2242
}
2243

2244
// MakeTaprootSCtrlBlock takes a leaf script, the internal key (usually the
2245
// revoke key), and a script tree and creates a valid control block for a spend
2246
// of the leaf.
2247
func MakeTaprootCtrlBlock(leafScript []byte, internalKey *btcec.PublicKey,
2248
        scriptTree *txscript.IndexedTapScriptTree) txscript.ControlBlock {
4✔
2249

4✔
2250
        tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
4✔
2251
        scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
4✔
2252
        settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
4✔
2253

4✔
2254
        return settleMerkleProof.ToControlBlock(internalKey)
4✔
2255
}
4✔
2256

2257
// TaprootCommitSpendSuccess constructs a valid witness allowing a node to
2258
// sweep the settled taproot output after the delay has passed for a force
2259
// close.
2260
func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
2261
        sweepTx *wire.MsgTx,
2262
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
2263

4✔
2264
        // First, we'll need to construct a valid control block to execute the
4✔
2265
        // leaf script for sweep settlement.
4✔
2266
        //
4✔
2267
        // TODO(roasbeef); make into closure instead? only need reovke key and
4✔
2268
        // scriptTree to make the ctrl block -- then default version that would
4✔
2269
        // take froms ign desc?
4✔
2270
        var ctrlBlockBytes []byte
4✔
2271
        if signDesc.ControlBlock == nil {
4✔
UNCOV
2272
                settleControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2273
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2274
                )
×
UNCOV
2275
                ctrlBytes, err := settleControlBlock.ToBytes()
×
UNCOV
2276
                if err != nil {
×
2277
                        return nil, err
×
2278
                }
×
2279

UNCOV
2280
                ctrlBlockBytes = ctrlBytes
×
2281
        } else {
4✔
2282
                ctrlBlockBytes = signDesc.ControlBlock
4✔
2283
        }
4✔
2284

2285
        // With the control block created, we'll now generate the signature we
2286
        // need to authorize the spend.
2287
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2288
        if err != nil {
4✔
2289
                return nil, err
×
2290
        }
×
2291

2292
        // The final witness stack will be:
2293
        //
2294
        //  <sweep sig> <sweep script> <control block>
2295
        witnessStack := make(wire.TxWitness, 3)
4✔
2296
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
2297
        witnessStack[1] = signDesc.WitnessScript
4✔
2298
        witnessStack[2] = ctrlBlockBytes
4✔
2299
        if err != nil {
4✔
2300
                return nil, err
×
2301
        }
×
2302

2303
        return witnessStack, nil
4✔
2304
}
2305

2306
// TaprootCommitSpendRevoke constructs a valid witness allowing a node to sweep
2307
// the revoked taproot output of a malicious peer.
2308
func TaprootCommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2309
        revokeTx *wire.MsgTx,
2310
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
2311

4✔
2312
        // First, we'll need to construct a valid control block to execute the
4✔
2313
        // leaf script for revocation path.
4✔
2314
        var ctrlBlockBytes []byte
4✔
2315
        if signDesc.ControlBlock == nil {
4✔
UNCOV
2316
                revokeCtrlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2317
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2318
                )
×
UNCOV
2319
                revokeBytes, err := revokeCtrlBlock.ToBytes()
×
UNCOV
2320
                if err != nil {
×
2321
                        return nil, err
×
2322
                }
×
2323

UNCOV
2324
                ctrlBlockBytes = revokeBytes
×
2325
        } else {
4✔
2326
                ctrlBlockBytes = signDesc.ControlBlock
4✔
2327
        }
4✔
2328

2329
        // With the control block created, we'll now generate the signature we
2330
        // need to authorize the spend.
2331
        revokeSig, err := signer.SignOutputRaw(revokeTx, signDesc)
4✔
2332
        if err != nil {
4✔
2333
                return nil, err
×
2334
        }
×
2335

2336
        // The final witness stack will be:
2337
        //
2338
        //  <revoke sig sig> <revoke script> <control block>
2339
        witnessStack := make(wire.TxWitness, 3)
4✔
2340
        witnessStack[0] = maybeAppendSighash(revokeSig, signDesc.HashType)
4✔
2341
        witnessStack[1] = signDesc.WitnessScript
4✔
2342
        witnessStack[2] = ctrlBlockBytes
4✔
2343

4✔
2344
        return witnessStack, nil
4✔
2345
}
2346

2347
// LeaseCommitScriptToSelf constructs the public key script for the output on the
2348
// commitment transaction paying to the "owner" of said commitment transaction.
2349
// If the other party learns of the preimage to the revocation hash, then they
2350
// can claim all the settled funds in the channel, plus the unsettled funds.
2351
//
2352
// Possible Input Scripts:
2353
//
2354
//        REVOKE:     <sig> 1
2355
//        SENDRSWEEP: <sig> <emptyvector>
2356
//
2357
// Output Script:
2358
//
2359
//        OP_IF
2360
//            <revokeKey>
2361
//        OP_ELSE
2362
//            <absoluteLeaseExpiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
2363
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
2364
//            <selfKey>
2365
//        OP_ENDIF
2366
//        OP_CHECKSIG
2367
func LeaseCommitScriptToSelf(selfKey, revokeKey *btcec.PublicKey,
2368
        csvTimeout, leaseExpiry uint32) ([]byte, error) {
4✔
2369

4✔
2370
        // This script is spendable under two conditions: either the
4✔
2371
        // 'csvTimeout' has passed and we can redeem our funds, or they can
4✔
2372
        // produce a valid signature with the revocation public key. The
4✔
2373
        // revocation public key will *only* be known to the other party if we
4✔
2374
        // have divulged the revocation hash, allowing them to homomorphically
4✔
2375
        // derive the proper private key which corresponds to the revoke public
4✔
2376
        // key.
4✔
2377
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
2378
                ToLocalScriptSize + LeaseWitnessScriptSizeOverhead,
4✔
2379
        ))
4✔
2380

4✔
2381
        builder.AddOp(txscript.OP_IF)
4✔
2382

4✔
2383
        // If a valid signature using the revocation key is presented, then
4✔
2384
        // allow an immediate spend provided the proper signature.
4✔
2385
        builder.AddData(revokeKey.SerializeCompressed())
4✔
2386

4✔
2387
        builder.AddOp(txscript.OP_ELSE)
4✔
2388

4✔
2389
        // Otherwise, we can re-claim our funds after once the CLTV lease
4✔
2390
        // maturity has been met, along with the CSV delay of 'csvTimeout'
4✔
2391
        // timeout blocks, and a valid signature.
4✔
2392
        builder.AddInt64(int64(leaseExpiry))
4✔
2393
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
4✔
2394
        builder.AddOp(txscript.OP_DROP)
4✔
2395

4✔
2396
        builder.AddInt64(int64(csvTimeout))
4✔
2397
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2398
        builder.AddOp(txscript.OP_DROP)
4✔
2399

4✔
2400
        builder.AddData(selfKey.SerializeCompressed())
4✔
2401

4✔
2402
        builder.AddOp(txscript.OP_ENDIF)
4✔
2403

4✔
2404
        // Finally, we'll validate the signature against the public key that's
4✔
2405
        // left on the top of the stack.
4✔
2406
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2407

4✔
2408
        return builder.Script()
4✔
2409
}
4✔
2410

2411
// CommitSpendTimeout constructs a valid witness allowing the owner of a
2412
// particular commitment transaction to spend the output returning settled
2413
// funds back to themselves after a relative block timeout.  In order to
2414
// properly spend the transaction, the target input's sequence number should be
2415
// set accordingly based off of the target relative block timeout within the
2416
// redeem script.  Additionally, OP_CSV requires that the version of the
2417
// transaction spending a pkscript with OP_CSV within it *must* be >= 2.
2418
func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
2419
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
2420

4✔
2421
        // Ensure the transaction version supports the validation of sequence
4✔
2422
        // locks and CSV semantics.
4✔
2423
        if sweepTx.Version < 2 {
4✔
2424
                return nil, fmt.Errorf("version of passed transaction MUST "+
×
2425
                        "be >= 2, not %v", sweepTx.Version)
×
2426
        }
×
2427

2428
        // With the sequence number in place, we're now able to properly sign
2429
        // off on the sweep transaction.
2430
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2431
        if err != nil {
4✔
2432
                return nil, err
×
2433
        }
×
2434

2435
        // Place an empty byte as the first item in the evaluated witness stack
2436
        // to force script execution to the timeout spend clause. We need to
2437
        // place an empty byte in order to ensure our script is still valid
2438
        // from the PoV of nodes that are enforcing minimal OP_IF/OP_NOTIF.
2439
        witnessStack := wire.TxWitness(make([][]byte, 3))
4✔
2440
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
2441
        witnessStack[1] = nil
4✔
2442
        witnessStack[2] = signDesc.WitnessScript
4✔
2443

4✔
2444
        return witnessStack, nil
4✔
2445
}
2446

2447
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
2448
// settled output of a malicious counterparty who broadcasts a revoked
2449
// commitment transaction.
2450
//
2451
// NOTE: The passed SignDescriptor should include the raw (untweaked)
2452
// revocation base public key of the receiver and also the proper double tweak
2453
// value based on the commitment secret of the revoked commitment.
2454
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2455
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
2456

4✔
2457
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2458
        if err != nil {
4✔
2459
                return nil, err
×
2460
        }
×
2461

2462
        // Place a 1 as the first item in the evaluated witness stack to
2463
        // force script execution to the revocation clause.
2464
        witnessStack := wire.TxWitness(make([][]byte, 3))
4✔
2465
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
2466
        witnessStack[1] = []byte{1}
4✔
2467
        witnessStack[2] = signDesc.WitnessScript
4✔
2468

4✔
2469
        return witnessStack, nil
4✔
2470
}
2471

2472
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
2473
// settled no-delay output on the counterparty's commitment transaction. If the
2474
// tweakless field is true, then we'll omit the set where we tweak the pubkey
2475
// with a random set of bytes, and use it directly in the witness stack.
2476
//
2477
// NOTE: The passed SignDescriptor should include the raw (untweaked) public
2478
// key of the receiver and also the proper single tweak value based on the
2479
// current commitment point.
2480
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
2481
        sweepTx *wire.MsgTx, tweakless bool) (wire.TxWitness, error) {
4✔
2482

4✔
2483
        if signDesc.KeyDesc.PubKey == nil {
4✔
2484
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2485
                        "KeyDesc pubkey")
×
2486
        }
×
2487

2488
        // This is just a regular p2wkh spend which looks something like:
2489
        //  * witness: <sig> <pubkey>
2490
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2491
        if err != nil {
4✔
2492
                return nil, err
×
2493
        }
×
2494

2495
        // Finally, we'll manually craft the witness. The witness here is the
2496
        // exact same as a regular p2wkh witness, depending on the value of the
2497
        // tweakless bool.
2498
        witness := make([][]byte, 2)
4✔
2499
        witness[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
2500

4✔
2501
        switch tweakless {
4✔
2502
        // If we're tweaking the key, then we use the tweaked public key as the
2503
        // last item in the witness stack which was originally used to created
2504
        // the pkScript we're spending.
2505
        case false:
4✔
2506
                witness[1] = TweakPubKeyWithTweak(
4✔
2507
                        signDesc.KeyDesc.PubKey, signDesc.SingleTweak,
4✔
2508
                ).SerializeCompressed()
4✔
2509

2510
        // Otherwise, we can just use the raw pubkey, since there's no random
2511
        // value to be combined.
2512
        case true:
4✔
2513
                witness[1] = signDesc.KeyDesc.PubKey.SerializeCompressed()
4✔
2514
        }
2515

2516
        return witness, nil
4✔
2517
}
2518

2519
// CommitScriptUnencumbered constructs the public key script on the commitment
2520
// transaction paying to the "other" party. The constructed output is a normal
2521
// p2wkh output spendable immediately, requiring no contestation period.
2522
func CommitScriptUnencumbered(key *btcec.PublicKey) ([]byte, error) {
4✔
2523
        // This script goes to the "other" party, and is spendable immediately.
4✔
2524
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
2525
                P2WPKHSize,
4✔
2526
        ))
4✔
2527
        builder.AddOp(txscript.OP_0)
4✔
2528
        builder.AddData(btcutil.Hash160(key.SerializeCompressed()))
4✔
2529

4✔
2530
        return builder.Script()
4✔
2531
}
4✔
2532

2533
// CommitScriptToRemoteConfirmed constructs the script for the output on the
2534
// commitment transaction paying to the remote party of said commitment
2535
// transaction. The money can only be spend after one confirmation.
2536
//
2537
// Possible Input Scripts:
2538
//
2539
//        SWEEP: <sig>
2540
//
2541
// Output Script:
2542
//
2543
//        <key> OP_CHECKSIGVERIFY
2544
//        1 OP_CHECKSEQUENCEVERIFY
2545
func CommitScriptToRemoteConfirmed(key *btcec.PublicKey) ([]byte, error) {
4✔
2546
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
2547
                ToRemoteConfirmedScriptSize,
4✔
2548
        ))
4✔
2549

4✔
2550
        // Only the given key can spend the output.
4✔
2551
        builder.AddData(key.SerializeCompressed())
4✔
2552
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
4✔
2553

4✔
2554
        // Check that the it has one confirmation.
4✔
2555
        builder.AddOp(txscript.OP_1)
4✔
2556
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2557

4✔
2558
        return builder.Script()
4✔
2559
}
4✔
2560

2561
// NewRemoteCommitScriptTree constructs a new script tree for the remote party
2562
// to sweep their funds after a hard coded 1 block delay.
2563
func NewRemoteCommitScriptTree(remoteKey *btcec.PublicKey,
2564
) (*CommitScriptTree, error) {
4✔
2565

4✔
2566
        // First, construct the remote party's tapscript they'll use to sweep
4✔
2567
        // their outputs.
4✔
2568
        builder := txscript.NewScriptBuilder()
4✔
2569
        builder.AddData(schnorr.SerializePubKey(remoteKey))
4✔
2570
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2571
        builder.AddOp(txscript.OP_1)
4✔
2572
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2573
        builder.AddOp(txscript.OP_DROP)
4✔
2574

4✔
2575
        remoteScript, err := builder.Script()
4✔
2576
        if err != nil {
4✔
2577
                return nil, err
×
2578
        }
×
2579

2580
        // With this script constructed, we'll map that into a tapLeaf, then
2581
        // make a new tapscript root from that.
2582
        tapLeaf := txscript.NewBaseTapLeaf(remoteScript)
4✔
2583
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)
4✔
2584
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
4✔
2585

4✔
2586
        // Now that we have our root, we can arrive at the final output script
4✔
2587
        // by tweaking the internal key with this root.
4✔
2588
        toRemoteOutputKey := txscript.ComputeTaprootOutputKey(
4✔
2589
                &TaprootNUMSKey, tapScriptRoot[:],
4✔
2590
        )
4✔
2591

4✔
2592
        return &CommitScriptTree{
4✔
2593
                ScriptTree: ScriptTree{
4✔
2594
                        TaprootKey:    toRemoteOutputKey,
4✔
2595
                        TapscriptTree: tapScriptTree,
4✔
2596
                        TapscriptRoot: tapScriptRoot[:],
4✔
2597
                        InternalKey:   &TaprootNUMSKey,
4✔
2598
                },
4✔
2599
                SettleLeaf: tapLeaf,
4✔
2600
        }, nil
4✔
2601
}
2602

2603
// TaprootCommitScriptToRemote constructs a taproot witness program for the
2604
// output on the commitment transaction for the remote party. For the top level
2605
// key spend, we'll use a NUMs key to ensure that only the script path can be
2606
// taken. Using a set NUMs key here also means that recovery solutions can scan
2607
// the chain given knowledge of the public key for the remote party. We then
2608
// commit to a single tapscript leaf that holds the normal CSV 1 delay
2609
// script.
2610
//
2611
// Our single tapleaf will use the following script:
2612
//
2613
//        <remotepubkey> OP_CHECKSIG
2614
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
2615
func TaprootCommitScriptToRemote(remoteKey *btcec.PublicKey,
2616
) (*btcec.PublicKey, error) {
×
2617

×
2618
        commitScriptTree, err := NewRemoteCommitScriptTree(remoteKey)
×
2619
        if err != nil {
×
2620
                return nil, err
×
2621
        }
×
2622

2623
        return commitScriptTree.TaprootKey, nil
×
2624
}
2625

2626
// TaprootCommitRemoteSpend allows the remote party to sweep their output into
2627
// their wallet after an enforced 1 block delay.
2628
func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
2629
        sweepTx *wire.MsgTx,
2630
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
4✔
2631

4✔
2632
        // First, we'll need to construct a valid control block to execute the
4✔
2633
        // leaf script for sweep settlement.
4✔
2634
        var ctrlBlockBytes []byte
4✔
2635
        if signDesc.ControlBlock == nil {
4✔
UNCOV
2636
                settleControlBlock := MakeTaprootCtrlBlock(
×
UNCOV
2637
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
×
UNCOV
2638
                )
×
UNCOV
2639
                ctrlBytes, err := settleControlBlock.ToBytes()
×
UNCOV
2640
                if err != nil {
×
2641
                        return nil, err
×
2642
                }
×
2643

UNCOV
2644
                ctrlBlockBytes = ctrlBytes
×
2645
        } else {
4✔
2646
                ctrlBlockBytes = signDesc.ControlBlock
4✔
2647
        }
4✔
2648

2649
        // With the control block created, we'll now generate the signature we
2650
        // need to authorize the spend.
2651
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2652
        if err != nil {
4✔
2653
                return nil, err
×
2654
        }
×
2655

2656
        // The final witness stack will be:
2657
        //
2658
        //  <sweep sig> <sweep script> <control block>
2659
        witnessStack := make(wire.TxWitness, 3)
4✔
2660
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
2661
        witnessStack[1] = signDesc.WitnessScript
4✔
2662
        witnessStack[2] = ctrlBlockBytes
4✔
2663

4✔
2664
        return witnessStack, nil
4✔
2665
}
2666

2667
// LeaseCommitScriptToRemoteConfirmed constructs the script for the output on
2668
// the commitment transaction paying to the remote party of said commitment
2669
// transaction. The money can only be spend after one confirmation.
2670
//
2671
// Possible Input Scripts:
2672
//
2673
//        SWEEP: <sig>
2674
//
2675
// Output Script:
2676
//
2677
//                <key> OP_CHECKSIGVERIFY
2678
//             <lease maturity in blocks> OP_CHECKLOCKTIMEVERIFY OP_DROP
2679
//                1 OP_CHECKSEQUENCEVERIFY
2680
func LeaseCommitScriptToRemoteConfirmed(key *btcec.PublicKey,
2681
        leaseExpiry uint32) ([]byte, error) {
4✔
2682

4✔
2683
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(45))
4✔
2684

4✔
2685
        // Only the given key can spend the output.
4✔
2686
        builder.AddData(key.SerializeCompressed())
4✔
2687
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
4✔
2688

4✔
2689
        // The channel initiator always has the additional channel lease
4✔
2690
        // expiration constraint for outputs that pay to them which must be
4✔
2691
        // satisfied.
4✔
2692
        builder.AddInt64(int64(leaseExpiry))
4✔
2693
        builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
4✔
2694
        builder.AddOp(txscript.OP_DROP)
4✔
2695

4✔
2696
        // Check that it has one confirmation.
4✔
2697
        builder.AddOp(txscript.OP_1)
4✔
2698
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2699

4✔
2700
        return builder.Script()
4✔
2701
}
4✔
2702

2703
// CommitSpendToRemoteConfirmed constructs a valid witness allowing a node to
2704
// spend their settled output on the counterparty's commitment transaction when
2705
// it has one confirmetion. This is used for the anchor channel type. The
2706
// spending key will always be non-tweaked for this output type.
2707
func CommitSpendToRemoteConfirmed(signer Signer, signDesc *SignDescriptor,
2708
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
2709

4✔
2710
        if signDesc.KeyDesc.PubKey == nil {
4✔
2711
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2712
                        "KeyDesc pubkey")
×
2713
        }
×
2714

2715
        // Similar to non delayed output, only a signature is needed.
2716
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2717
        if err != nil {
4✔
2718
                return nil, err
×
2719
        }
×
2720

2721
        // Finally, we'll manually craft the witness. The witness here is the
2722
        // signature and the redeem script.
2723
        witnessStack := make([][]byte, 2)
4✔
2724
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
2725
        witnessStack[1] = signDesc.WitnessScript
4✔
2726

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

2730
// CommitScriptAnchor constructs the script for the anchor output spendable by
2731
// the given key immediately, or by anyone after 16 confirmations.
2732
//
2733
// Possible Input Scripts:
2734
//
2735
//        By owner:                                <sig>
2736
//        By anyone (after 16 conf):        <emptyvector>
2737
//
2738
// Output Script:
2739
//
2740
//        <funding_pubkey> OP_CHECKSIG OP_IFDUP
2741
//        OP_NOTIF
2742
//          OP_16 OP_CSV
2743
//        OP_ENDIF
2744
func CommitScriptAnchor(key *btcec.PublicKey) ([]byte, error) {
4✔
2745
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
4✔
2746
                AnchorScriptSize,
4✔
2747
        ))
4✔
2748

4✔
2749
        // Spend immediately with key.
4✔
2750
        builder.AddData(key.SerializeCompressed())
4✔
2751
        builder.AddOp(txscript.OP_CHECKSIG)
4✔
2752

4✔
2753
        // Duplicate the value if true, since it will be consumed by the NOTIF.
4✔
2754
        builder.AddOp(txscript.OP_IFDUP)
4✔
2755

4✔
2756
        // Otherwise spendable by anyone after 16 confirmations.
4✔
2757
        builder.AddOp(txscript.OP_NOTIF)
4✔
2758
        builder.AddOp(txscript.OP_16)
4✔
2759
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2760
        builder.AddOp(txscript.OP_ENDIF)
4✔
2761

4✔
2762
        return builder.Script()
4✔
2763
}
4✔
2764

2765
// AnchorScriptTree holds all the contents needed to sweep a taproot anchor
2766
// output on chain.
2767
type AnchorScriptTree struct {
2768
        ScriptTree
2769

2770
        // SweepLeaf is the leaf used to settle the output after the delay.
2771
        SweepLeaf txscript.TapLeaf
2772
}
2773

2774
// NewAnchorScriptTree makes a new script tree for an anchor output with the
2775
// passed anchor key.
2776
func NewAnchorScriptTree(anchorKey *btcec.PublicKey,
2777
) (*AnchorScriptTree, error) {
4✔
2778

4✔
2779
        // The main script used is just a OP_16 CSV (anyone can sweep after 16
4✔
2780
        // blocks).
4✔
2781
        builder := txscript.NewScriptBuilder()
4✔
2782
        builder.AddOp(txscript.OP_16)
4✔
2783
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
4✔
2784

4✔
2785
        anchorScript, err := builder.Script()
4✔
2786
        if err != nil {
4✔
2787
                return nil, err
×
2788
        }
×
2789

2790
        // With the script, we can make our sole leaf, then derive the root
2791
        // from that.
2792
        tapLeaf := txscript.NewBaseTapLeaf(anchorScript)
4✔
2793
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)
4✔
2794
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
4✔
2795

4✔
2796
        // Now that we have our root, we can arrive at the final output script
4✔
2797
        // by tweaking the internal key with this root.
4✔
2798
        anchorOutputKey := txscript.ComputeTaprootOutputKey(
4✔
2799
                anchorKey, tapScriptRoot[:],
4✔
2800
        )
4✔
2801

4✔
2802
        return &AnchorScriptTree{
4✔
2803
                ScriptTree: ScriptTree{
4✔
2804
                        TaprootKey:    anchorOutputKey,
4✔
2805
                        TapscriptTree: tapScriptTree,
4✔
2806
                        TapscriptRoot: tapScriptRoot[:],
4✔
2807
                        InternalKey:   anchorKey,
4✔
2808
                },
4✔
2809
                SweepLeaf: tapLeaf,
4✔
2810
        }, nil
4✔
2811
}
2812

2813
// WitnessScript returns the witness script that we'll use when signing for the
2814
// remote party, and also verifying signatures on our transactions. As an
2815
// example, when we create an outgoing HTLC for the remote party, we want to
2816
// sign their success path.
2817
func (a *AnchorScriptTree) WitnessScriptToSign() []byte {
×
2818
        return a.SweepLeaf.Script
×
2819
}
×
2820

2821
// WitnessScriptForPath returns the witness script for the given spending path.
2822
// An error is returned if the path is unknown.
2823
func (a *AnchorScriptTree) WitnessScriptForPath(path ScriptPath,
2824
) ([]byte, error) {
4✔
2825

4✔
2826
        switch path {
4✔
2827
        case ScriptPathDelay:
×
2828
                fallthrough
×
2829
        case ScriptPathSuccess:
4✔
2830
                return a.SweepLeaf.Script, nil
4✔
2831

2832
        default:
×
2833
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2834
        }
2835
}
2836

2837
// CtrlBlockForPath returns the control block for the given spending path. For
2838
// script types that don't have a control block, nil is returned.
2839
func (a *AnchorScriptTree) CtrlBlockForPath(path ScriptPath,
2840
) (*txscript.ControlBlock, error) {
×
2841

×
2842
        switch path {
×
2843
        case ScriptPathDelay:
×
2844
                fallthrough
×
2845
        case ScriptPathSuccess:
×
2846
                return lnutils.Ptr(MakeTaprootCtrlBlock(
×
2847
                        a.SweepLeaf.Script, a.InternalKey,
×
2848
                        a.TapscriptTree,
×
2849
                )), nil
×
2850

2851
        default:
×
2852
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2853
        }
2854
}
2855

2856
// A compile time check to ensure AnchorScriptTree implements the
2857
// TapscriptDescriptor interface.
2858
var _ TapscriptDescriptor = (*AnchorScriptTree)(nil)
2859

2860
// TaprootOutputKeyAnchor returns the segwit v1 (taproot) witness program that
2861
// encodes the anchor output spending conditions: the passed key can be used
2862
// for keyspend, with the OP_CSV 16 clause living within an internal tapscript
2863
// leaf.
2864
//
2865
// Spend paths:
2866
//   - Key spend: <key_signature>
2867
//   - Script spend: OP_16 CSV <control_block>
2868
func TaprootOutputKeyAnchor(key *btcec.PublicKey) (*btcec.PublicKey, error) {
×
2869
        anchorScriptTree, err := NewAnchorScriptTree(key)
×
2870
        if err != nil {
×
2871
                return nil, err
×
2872
        }
×
2873

2874
        return anchorScriptTree.TaprootKey, nil
×
2875
}
2876

2877
// TaprootAnchorSpend constructs a valid witness allowing a node to sweep their
2878
// anchor output.
2879
func TaprootAnchorSpend(signer Signer, signDesc *SignDescriptor,
2880
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
2881

4✔
2882
        // For this spend type, we only need a single signature which'll be a
4✔
2883
        // keyspend using the anchor private key.
4✔
2884
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2885
        if err != nil {
4✔
2886
                return nil, err
×
2887
        }
×
2888

2889
        // The witness stack in this case is pretty simple: we only need to
2890
        // specify the signature generated.
2891
        witnessStack := make(wire.TxWitness, 1)
4✔
2892
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
4✔
2893

4✔
2894
        return witnessStack, nil
4✔
2895
}
2896

2897
// TaprootAnchorSpendAny constructs a valid witness allowing anyone to sweep
2898
// the anchor output after 16 blocks.
UNCOV
2899
func TaprootAnchorSpendAny(anchorKey *btcec.PublicKey) (wire.TxWitness, error) {
×
UNCOV
2900
        anchorScriptTree, err := NewAnchorScriptTree(anchorKey)
×
UNCOV
2901
        if err != nil {
×
2902
                return nil, err
×
2903
        }
×
2904

2905
        // For this spend, the only thing we need to do is create a valid
2906
        // control block. Other than that, there're no restrictions to how the
2907
        // output can be spent.
UNCOV
2908
        scriptTree := anchorScriptTree.TapscriptTree
×
UNCOV
2909
        sweepLeaf := anchorScriptTree.SweepLeaf
×
UNCOV
2910
        sweepIdx := scriptTree.LeafProofIndex[sweepLeaf.TapHash()]
×
UNCOV
2911
        sweepMerkleProof := scriptTree.LeafMerkleProofs[sweepIdx]
×
UNCOV
2912
        sweepControlBlock := sweepMerkleProof.ToControlBlock(anchorKey)
×
UNCOV
2913

×
UNCOV
2914
        // The final witness stack will be:
×
UNCOV
2915
        //
×
UNCOV
2916
        //  <sweep script> <control block>
×
UNCOV
2917
        witnessStack := make(wire.TxWitness, 2)
×
UNCOV
2918
        witnessStack[0] = sweepLeaf.Script
×
UNCOV
2919
        witnessStack[1], err = sweepControlBlock.ToBytes()
×
UNCOV
2920
        if err != nil {
×
2921
                return nil, err
×
2922
        }
×
2923

UNCOV
2924
        return witnessStack, nil
×
2925
}
2926

2927
// CommitSpendAnchor constructs a valid witness allowing a node to spend their
2928
// anchor output on the commitment transaction using their funding key. This is
2929
// used for the anchor channel type.
2930
func CommitSpendAnchor(signer Signer, signDesc *SignDescriptor,
2931
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
2932

4✔
2933
        if signDesc.KeyDesc.PubKey == nil {
4✔
2934
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2935
                        "KeyDesc pubkey")
×
2936
        }
×
2937

2938
        // Create a signature.
2939
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
2940
        if err != nil {
4✔
2941
                return nil, err
×
2942
        }
×
2943

2944
        // The witness here is just a signature and the redeem script.
2945
        witnessStack := make([][]byte, 2)
4✔
2946
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
4✔
2947
        witnessStack[1] = signDesc.WitnessScript
4✔
2948

4✔
2949
        return witnessStack, nil
4✔
2950
}
2951

2952
// CommitSpendAnchorAnyone constructs a witness allowing anyone to spend the
2953
// anchor output after it has gotten 16 confirmations. Since no signing is
2954
// required, only knowledge of the redeem script is necessary to spend it.
UNCOV
2955
func CommitSpendAnchorAnyone(script []byte) (wire.TxWitness, error) {
×
UNCOV
2956
        // The witness here is just the redeem script.
×
UNCOV
2957
        witnessStack := make([][]byte, 2)
×
UNCOV
2958
        witnessStack[0] = nil
×
UNCOV
2959
        witnessStack[1] = script
×
UNCOV
2960

×
UNCOV
2961
        return witnessStack, nil
×
UNCOV
2962
}
×
2963

2964
// SingleTweakBytes computes set of bytes we call the single tweak. The purpose
2965
// of the single tweak is to randomize all regular delay and payment base
2966
// points. To do this, we generate a hash that binds the commitment point to
2967
// the pay/delay base point. The end result is that the basePoint is
2968
// tweaked as follows:
2969
//
2970
//   - key = basePoint + sha256(commitPoint || basePoint)*G
2971
func SingleTweakBytes(commitPoint, basePoint *btcec.PublicKey) []byte {
4✔
2972
        h := sha256.New()
4✔
2973
        h.Write(commitPoint.SerializeCompressed())
4✔
2974
        h.Write(basePoint.SerializeCompressed())
4✔
2975
        return h.Sum(nil)
4✔
2976
}
4✔
2977

2978
// TweakPubKey tweaks a public base point given a per commitment point. The per
2979
// commitment point is a unique point on our target curve for each commitment
2980
// transaction. When tweaking a local base point for use in a remote commitment
2981
// transaction, the remote party's current per commitment point is to be used.
2982
// The opposite applies for when tweaking remote keys. Precisely, the following
2983
// operation is used to "tweak" public keys:
2984
//
2985
//        tweakPub := basePoint + sha256(commitPoint || basePoint) * G
2986
//                 := G*k + sha256(commitPoint || basePoint)*G
2987
//                 := G*(k + sha256(commitPoint || basePoint))
2988
//
2989
// Therefore, if a party possess the value k, the private key of the base
2990
// point, then they are able to derive the proper private key for the
2991
// revokeKey by computing:
2992
//
2993
//        revokePriv := k + sha256(commitPoint || basePoint) mod N
2994
//
2995
// Where N is the order of the sub-group.
2996
//
2997
// The rationale for tweaking all public keys used within the commitment
2998
// contracts is to ensure that all keys are properly delinearized to avoid any
2999
// funny business when jointly collaborating to compute public and private
3000
// keys. Additionally, the use of the per commitment point ensures that each
3001
// commitment state houses a unique set of keys which is useful when creating
3002
// blinded channel outsourcing protocols.
3003
//
3004
// TODO(roasbeef): should be using double-scalar mult here
3005
func TweakPubKey(basePoint, commitPoint *btcec.PublicKey) *btcec.PublicKey {
4✔
3006
        tweakBytes := SingleTweakBytes(commitPoint, basePoint)
4✔
3007
        return TweakPubKeyWithTweak(basePoint, tweakBytes)
4✔
3008
}
4✔
3009

3010
// TweakPubKeyWithTweak is the exact same as the TweakPubKey function, however
3011
// it accepts the raw tweak bytes directly rather than the commitment point.
3012
func TweakPubKeyWithTweak(pubKey *btcec.PublicKey,
3013
        tweakBytes []byte) *btcec.PublicKey {
4✔
3014

4✔
3015
        var (
4✔
3016
                pubKeyJacobian btcec.JacobianPoint
4✔
3017
                tweakJacobian  btcec.JacobianPoint
4✔
3018
                resultJacobian btcec.JacobianPoint
4✔
3019
        )
4✔
3020
        tweakKey, _ := btcec.PrivKeyFromBytes(tweakBytes)
4✔
3021
        btcec.ScalarBaseMultNonConst(&tweakKey.Key, &tweakJacobian)
4✔
3022

4✔
3023
        pubKey.AsJacobian(&pubKeyJacobian)
4✔
3024
        btcec.AddNonConst(&pubKeyJacobian, &tweakJacobian, &resultJacobian)
4✔
3025

4✔
3026
        resultJacobian.ToAffine()
4✔
3027
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
4✔
3028
}
4✔
3029

3030
// TweakPrivKey tweaks the private key of a public base point given a per
3031
// commitment point. The per commitment secret is the revealed revocation
3032
// secret for the commitment state in question. This private key will only need
3033
// to be generated in the case that a channel counter party broadcasts a
3034
// revoked state. Precisely, the following operation is used to derive a
3035
// tweaked private key:
3036
//
3037
//   - tweakPriv := basePriv + sha256(commitment || basePub) mod N
3038
//
3039
// Where N is the order of the sub-group.
3040
func TweakPrivKey(basePriv *btcec.PrivateKey,
3041
        commitTweak []byte) *btcec.PrivateKey {
4✔
3042

4✔
3043
        // tweakInt := sha256(commitPoint || basePub)
4✔
3044
        tweakScalar := new(btcec.ModNScalar)
4✔
3045
        tweakScalar.SetByteSlice(commitTweak)
4✔
3046

4✔
3047
        tweakScalar.Add(&basePriv.Key)
4✔
3048

4✔
3049
        return &btcec.PrivateKey{Key: *tweakScalar}
4✔
3050
}
4✔
3051

3052
// DeriveRevocationPubkey derives the revocation public key given the
3053
// counterparty's commitment key, and revocation preimage derived via a
3054
// pseudo-random-function. In the event that we (for some reason) broadcast a
3055
// revoked commitment transaction, then if the other party knows the revocation
3056
// preimage, then they'll be able to derive the corresponding private key to
3057
// this private key by exploiting the homomorphism in the elliptic curve group:
3058
//   - https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
3059
//
3060
// The derivation is performed as follows:
3061
//
3062
//        revokeKey := revokeBase * sha256(revocationBase || commitPoint) +
3063
//                     commitPoint * sha256(commitPoint || revocationBase)
3064
//
3065
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint)) +
3066
//                     G*(commitSecret * sha256(commitPoint || revocationBase))
3067
//
3068
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint) +
3069
//                        commitSecret * sha256(commitPoint || revocationBase))
3070
//
3071
// Therefore, once we divulge the revocation secret, the remote peer is able to
3072
// compute the proper private key for the revokeKey by computing:
3073
//
3074
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3075
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3076
//
3077
// Where N is the order of the sub-group.
3078
func DeriveRevocationPubkey(revokeBase,
3079
        commitPoint *btcec.PublicKey) *btcec.PublicKey {
4✔
3080

4✔
3081
        // R = revokeBase * sha256(revocationBase || commitPoint)
4✔
3082
        revokeTweakBytes := SingleTweakBytes(revokeBase, commitPoint)
4✔
3083
        revokeTweakScalar := new(btcec.ModNScalar)
4✔
3084
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
4✔
3085

4✔
3086
        var (
4✔
3087
                revokeBaseJacobian btcec.JacobianPoint
4✔
3088
                rJacobian          btcec.JacobianPoint
4✔
3089
        )
4✔
3090
        revokeBase.AsJacobian(&revokeBaseJacobian)
4✔
3091
        btcec.ScalarMultNonConst(
4✔
3092
                revokeTweakScalar, &revokeBaseJacobian, &rJacobian,
4✔
3093
        )
4✔
3094

4✔
3095
        // C = commitPoint * sha256(commitPoint || revocationBase)
4✔
3096
        commitTweakBytes := SingleTweakBytes(commitPoint, revokeBase)
4✔
3097
        commitTweakScalar := new(btcec.ModNScalar)
4✔
3098
        commitTweakScalar.SetByteSlice(commitTweakBytes)
4✔
3099

4✔
3100
        var (
4✔
3101
                commitPointJacobian btcec.JacobianPoint
4✔
3102
                cJacobian           btcec.JacobianPoint
4✔
3103
        )
4✔
3104
        commitPoint.AsJacobian(&commitPointJacobian)
4✔
3105
        btcec.ScalarMultNonConst(
4✔
3106
                commitTweakScalar, &commitPointJacobian, &cJacobian,
4✔
3107
        )
4✔
3108

4✔
3109
        // Now that we have the revocation point, we add this to their commitment
4✔
3110
        // public key in order to obtain the revocation public key.
4✔
3111
        //
4✔
3112
        // P = R + C
4✔
3113
        var resultJacobian btcec.JacobianPoint
4✔
3114
        btcec.AddNonConst(&rJacobian, &cJacobian, &resultJacobian)
4✔
3115

4✔
3116
        resultJacobian.ToAffine()
4✔
3117
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
4✔
3118
}
4✔
3119

3120
// DeriveRevocationPrivKey derives the revocation private key given a node's
3121
// commitment private key, and the preimage to a previously seen revocation
3122
// hash. Using this derived private key, a node is able to claim the output
3123
// within the commitment transaction of a node in the case that they broadcast
3124
// a previously revoked commitment transaction.
3125
//
3126
// The private key is derived as follows:
3127
//
3128
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3129
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3130
//
3131
// Where N is the order of the sub-group.
3132
func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
3133
        commitSecret *btcec.PrivateKey) *btcec.PrivateKey {
4✔
3134

4✔
3135
        // r = sha256(revokeBasePub || commitPoint)
4✔
3136
        revokeTweakBytes := SingleTweakBytes(
4✔
3137
                revokeBasePriv.PubKey(), commitSecret.PubKey(),
4✔
3138
        )
4✔
3139
        revokeTweakScalar := new(btcec.ModNScalar)
4✔
3140
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
4✔
3141

4✔
3142
        // c = sha256(commitPoint || revokeBasePub)
4✔
3143
        commitTweakBytes := SingleTweakBytes(
4✔
3144
                commitSecret.PubKey(), revokeBasePriv.PubKey(),
4✔
3145
        )
4✔
3146
        commitTweakScalar := new(btcec.ModNScalar)
4✔
3147
        commitTweakScalar.SetByteSlice(commitTweakBytes)
4✔
3148

4✔
3149
        // Finally to derive the revocation secret key we'll perform the
4✔
3150
        // following operation:
4✔
3151
        //
4✔
3152
        //  k = (revocationPriv * r) + (commitSecret * c) mod N
4✔
3153
        //
4✔
3154
        // This works since:
4✔
3155
        //  P = (G*a)*b + (G*c)*d
4✔
3156
        //  P = G*(a*b) + G*(c*d)
4✔
3157
        //  P = G*(a*b + c*d)
4✔
3158
        revokeHalfPriv := revokeTweakScalar.Mul(&revokeBasePriv.Key)
4✔
3159
        commitHalfPriv := commitTweakScalar.Mul(&commitSecret.Key)
4✔
3160

4✔
3161
        revocationPriv := revokeHalfPriv.Add(commitHalfPriv)
4✔
3162

4✔
3163
        return &btcec.PrivateKey{Key: *revocationPriv}
4✔
3164
}
4✔
3165

3166
// ComputeCommitmentPoint generates a commitment point given a commitment
3167
// secret. The commitment point for each state is used to randomize each key in
3168
// the key-ring and also to used as a tweak to derive new public+private keys
3169
// for the state.
3170
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
4✔
3171
        _, pubKey := btcec.PrivKeyFromBytes(commitSecret)
4✔
3172
        return pubKey
4✔
3173
}
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc