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

lightningnetwork / lnd / 13236757158

10 Feb 2025 08:39AM UTC coverage: 57.649% (-1.2%) from 58.815%
13236757158

Pull #9493

github

ziggie1984
lncli: for some cmds we don't replace the data of the response.

For some cmds it is not very practical to replace the json output
because we might pipe it into other commands. For example when
creating the route we want to pipe it into sendtoRoute.
Pull Request #9493: For some lncli cmds we should not replace the content with other data

0 of 9 new or added lines in 2 files covered. (0.0%)

19535 existing lines in 252 files now uncovered.

103517 of 179563 relevant lines covered (57.65%)

24878.49 hits per line

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

84.23
/input/script_utils.go
1
package input
2

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

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

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

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

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

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

45
        return *pub
79✔
46
}
47

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

145✔
267
        return witness
145✔
268
}
269

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

286
        return found, index
88✔
287
}
288

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5✔
454
        return witnessStack, nil
5✔
455
}
456

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

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

472
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
4✔
473
}
474

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

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

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

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

2✔
495
                return true, nil
2✔
496
        }
2✔
497

498
        return false, nil
2✔
499
}
500

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

98✔
818
        var hType htlcType
98✔
819
        if whoseCommit.IsLocal() {
146✔
820
                hType = htlcLocalOutgoing
48✔
821
        } else {
98✔
822
                hType = htlcRemoteIncoming
50✔
823
        }
50✔
824

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

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

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

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

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

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

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

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

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

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

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

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

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

914
                ctrlBlockBytes = ctrlBytes
16✔
UNCOV
915
        } else {
×
UNCOV
916
                ctrlBlockBytes = signDesc.ControlBlock
×
UNCOV
917
        }
×
918

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4,365✔
1084
        return builder.Script()
4,365✔
1085
}
1086

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

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

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

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

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

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

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

20✔
1146
        return witnessStack, nil
20✔
1147
}
1148

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

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

27✔
1162
        return revokeKey, nil
27✔
1163
}
1164

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

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

1180
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
19✔
1181
}
1182

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

115✔
1382
        var hType htlcType
115✔
1383
        if whoseCommit.IsLocal() {
167✔
1384
                hType = htlcLocalIncoming
52✔
1385
        } else {
115✔
1386
                hType = htlcRemoteOutgoing
63✔
1387
        }
63✔
1388

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

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

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

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

1427
                ctrlBlock = ctrlBytes
20✔
UNCOV
1428
        } else {
×
UNCOV
1429
                ctrlBlock = signDesc.ControlBlock
×
UNCOV
1430
        }
×
1431

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

7,947✔
1586
        return builder.Script()
7,947✔
1587
}
7,947✔
1588

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
1681
        return redemptionKey, nil
×
1682
}
1683

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

9✔
1804
        return witnessStack, nil
9✔
1805
}
1806

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

11✔
1965
        return witnessStack, nil
11✔
1966
}
1967

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

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

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

14✔
1990
        return witnessStack, nil
14✔
1991
}
1992

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

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

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

×
UNCOV
2021
        return witnessStack, nil
×
2022
}
2023

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

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

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

9,495✔
2072
        builder.AddOp(txscript.OP_IF)
9,495✔
2073

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

9,495✔
2078
        builder.AddOp(txscript.OP_ELSE)
9,495✔
2079

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

9,495✔
2087
        builder.AddOp(txscript.OP_ENDIF)
9,495✔
2088

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

9,495✔
2093
        return builder.Script()
9,495✔
2094
}
9,495✔
2095

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1,503✔
2240
        return builder.Script()
1,503✔
2241
}
1,503✔
2242

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

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

1,505✔
2254
        return builder.Script()
1,505✔
2255
}
1,505✔
2256

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

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

2300
        return commitScriptTree.TaprootKey, nil
×
2301
}
2302

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

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

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

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

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

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

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

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

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

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

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

2380
                ctrlBlockBytes = revokeBytes
9✔
2381
        } else {
684✔
2382
                ctrlBlockBytes = signDesc.ControlBlock
684✔
2383
        }
684✔
2384

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2572
        return witness, nil
29✔
2573
}
2574

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

9,154✔
2586
        return builder.Script()
9,154✔
2587
}
9,154✔
2588

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2686
        return commitScriptTree.TaprootKey, nil
×
2687
}
2688

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

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

2707
                ctrlBlockBytes = ctrlBytes
13✔
2708
        } else {
683✔
2709
                ctrlBlockBytes = signDesc.ControlBlock
683✔
2710
        }
683✔
2711

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2942
        return anchorScriptTree.TaprootKey, nil
×
2943
}
2944

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

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

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

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

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

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

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

2992
        return witnessStack, nil
2✔
2993
}
2994

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

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

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

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

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

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

3✔
3029
        return witnessStack, nil
3✔
3030
}
3✔
3031

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

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

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

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

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

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

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

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

7,561✔
3115
        tweakScalar.Add(&basePriv.Key)
7,561✔
3116

7,561✔
3117
        return &btcec.PrivateKey{Key: *tweakScalar}
7,561✔
3118
}
7,561✔
3119

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

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

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

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

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

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

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

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

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

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

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

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

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

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

© 2025 Coveralls, Inc