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

lightningnetwork / lnd / 23576325032

26 Mar 2026 03:39AM UTC coverage: 62.143% (+0.03%) from 62.117%
23576325032

Pull #9985

github

web-flow
Merge 12fb65217 into 46fbc10fc
Pull Request #9985: multi: implement awareness of the final/production taproot channel variant

440 of 588 new or added lines in 27 files covered. (74.83%)

94 existing lines in 22 files now uncovered.

141784 of 228159 relevant lines covered (62.14%)

19319.48 hits per line

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

86.21
/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
// TemplateParams is a type alias for the map[string]interface{} type used
24
// with txscript.ScriptTemplate to make code more readable.
25
type TemplateParams map[string]interface{}
26

27
var (
28
        // TODO(roasbeef): remove these and use the one's defined in txscript
29
        // within testnet-L.
30

31
        // SequenceLockTimeSeconds is the 22nd bit which indicates the lock
32
        // time is in seconds.
33
        SequenceLockTimeSeconds = uint32(1 << 22)
34
)
35

36
// MustParsePubKey parses a hex encoded public key string into a public key and
37
// panic if parsing fails.
38
func MustParsePubKey(pubStr string) btcec.PublicKey {
92✔
39
        pubBytes, err := hex.DecodeString(pubStr)
92✔
40
        if err != nil {
92✔
41
                panic(err)
×
42
        }
43

44
        pub, err := btcec.ParsePubKey(pubBytes)
92✔
45
        if err != nil {
92✔
46
                panic(err)
×
47
        }
48

49
        return *pub
92✔
50
}
51

52
// TaprootNUMSHex is the hex encoded version of the taproot NUMs key.
53
const TaprootNUMSHex = "02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb" +
54
        "6bf4bc130a279"
55

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

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

71
        // Verify return true if the ECDSA signature is valid for the passed
72
        // message digest under the provided public key.
73
        Verify([]byte, *btcec.PublicKey) bool
74
}
75

76
// ParseSignature parses a raw signature into an input.Signature instance. This
77
// routine supports parsing normal ECDSA DER encoded signatures, as well as
78
// schnorr signatures.
79
func ParseSignature(rawSig []byte) (Signature, error) {
114✔
80
        if len(rawSig) == schnorr.SignatureSize {
133✔
81
                return schnorr.ParseSignature(rawSig)
19✔
82
        }
19✔
83

84
        return ecdsa.ParseDERSignature(rawSig)
99✔
85
}
86

87
// WitnessScriptHash generates a pay-to-witness-script-hash public key script
88
// paying to a version 0 witness program paying to the passed redeem script.
89
func WitnessScriptHash(witnessScript []byte) ([]byte, error) {
29,655✔
90
        scriptHash := sha256.Sum256(witnessScript)
29,655✔
91
        return txscript.ScriptTemplate(
29,655✔
92
                `OP_0 {{ hex .ScriptHash }}`,
29,655✔
93
                txscript.WithScriptTemplateParams(TemplateParams{
29,655✔
94
                        "ScriptHash": scriptHash[:],
29,655✔
95
                }),
29,655✔
96
        )
29,655✔
97
}
29,655✔
98

99
// WitnessPubKeyHash generates a pay-to-witness-pubkey-hash public key script
100
// paying to a version 0 witness program containing the passed serialized
101
// public key.
102
func WitnessPubKeyHash(pubkey []byte) ([]byte, error) {
38✔
103
        pkhash := btcutil.Hash160(pubkey)
38✔
104
        return txscript.ScriptTemplate(
38✔
105
                `OP_0 {{ hex .PKHash }}`,
38✔
106
                txscript.WithScriptTemplateParams(TemplateParams{
38✔
107
                        "PKHash": pkhash,
38✔
108
                }),
38✔
109
        )
38✔
110
}
38✔
111

112
// GenerateP2SH generates a pay-to-script-hash public key script paying to the
113
// passed redeem script.
114
func GenerateP2SH(script []byte) ([]byte, error) {
8✔
115
        scriptHash := btcutil.Hash160(script)
8✔
116
        return txscript.ScriptTemplate(
8✔
117
                `OP_HASH160 {{ hex .ScriptHash }} OP_EQUAL`,
8✔
118
                txscript.WithScriptTemplateParams(TemplateParams{
8✔
119
                        "ScriptHash": scriptHash,
8✔
120
                }),
8✔
121
        )
8✔
122
}
8✔
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) {
7✔
127
        pkHash := btcutil.Hash160(pubkey)
7✔
128
        return txscript.ScriptTemplate(
7✔
129
                `OP_DUP OP_HASH160 {{ hex .pkh }} OP_EQUALVERIFY OP_CHECKSIG`,
7✔
130
                txscript.WithScriptTemplateParams(TemplateParams{
7✔
131
                        "pkh": pkHash,
7✔
132
                }),
7✔
133
        )
7✔
134
}
7✔
135

136
// GenerateUnknownWitness generates the maximum-sized witness public key script
137
// consisting of a version push and a 40-byte data push.
138
func GenerateUnknownWitness() ([]byte, error) {
492✔
139
        witnessScript := make([]byte, 40)
492✔
140
        return txscript.ScriptTemplate(
492✔
141
                `OP_0 {{ hex .WitnessScript }}`,
492✔
142
                txscript.WithScriptTemplateParams(TemplateParams{
492✔
143
                        "WitnessScript": witnessScript,
492✔
144
                }),
492✔
145
        )
492✔
146
}
492✔
147

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

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

164
        return txscript.ScriptTemplate(
2,019✔
165
                `OP_2 {{ hex .pubA }} {{ hex .pubB }} OP_2 OP_CHECKMULTISIG`,
2,019✔
166
                txscript.WithScriptTemplateParams(TemplateParams{
2,019✔
167
                        "pubA": aPub,
2,019✔
168
                        "pubB": bPub,
2,019✔
169
                }),
2,019✔
170
        )
2,019✔
171
}
172

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

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

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

195
        return witnessScript, wire.NewTxOut(amt, pkScript), nil
292✔
196
}
197

198
// GenTaprootFundingScript constructs the taproot-native funding output that
199
// uses MuSig2 to create a single aggregated key to anchor the channel.
200
func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
201
        amt int64, tapscriptRoot fn.Option[chainhash.Hash]) ([]byte,
202
        *wire.TxOut, error) {
121✔
203

121✔
204
        muSig2Opt := musig2.WithBIP86KeyTweak()
121✔
205
        tapscriptRoot.WhenSome(func(scriptRoot chainhash.Hash) {
153✔
206
                muSig2Opt = musig2.WithTaprootKeyTweak(scriptRoot[:])
32✔
207
        })
32✔
208

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

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

229
        txOut := wire.NewTxOut(amt, pkScript)
121✔
230

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

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

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

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

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

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

150✔
262
        return witness
150✔
263
}
264

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

281
        return found, index
96✔
282
}
283

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

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

3,924✔
336
        // Build the base script template. The script structure is:
3,924✔
337
        //   - Revocation path: hash the top-of-stack item and check if it
3,924✔
338
        //     matches the revocation key hash. If so, checksig.
3,924✔
339
        //   - Else branch: push the receiver's key, swap to expose the
3,924✔
340
        //     witness item, and check its size.
3,924✔
341
        //     - If not 32 bytes (timeout path): drop, then 2-of-2 multisig
3,924✔
342
        //       with sender+receiver HTLC keys.
3,924✔
343
        //     - If 32 bytes (preimage path): hash160-verify, then checksig
3,924✔
344
        //       with the receiver's key.
3,924✔
345
        //   - Optional 1-block CSV for confirmed spend.
3,924✔
346
        scriptTemplate := `
3,924✔
347
                OP_DUP OP_HASH160 {{ hex .RevKeyHash }} OP_EQUAL
3,924✔
348
                OP_IF
3,924✔
349
                        OP_CHECKSIG
3,924✔
350
                OP_ELSE
3,924✔
351
                        {{ hex .ReceiverKey }}
3,924✔
352
                        OP_SWAP
3,924✔
353
                        OP_SIZE 32 OP_EQUAL
3,924✔
354
                        OP_NOTIF
3,924✔
355
                                OP_DROP 2 OP_SWAP
3,924✔
356
                                {{ hex .SenderKey }} 2 OP_CHECKMULTISIG
3,924✔
357
                        OP_ELSE
3,924✔
358
                                OP_HASH160 {{ hex .PaymentHashRipemd }}
3,924✔
359
                                OP_EQUALVERIFY
3,924✔
360
                                OP_CHECKSIG
3,924✔
361
                        OP_ENDIF
3,924✔
362
        `
3,924✔
363

3,924✔
364
        // Add 1 block CSV delay if a confirmation is required for the
3,924✔
365
        // non-revocation clauses.
3,924✔
366
        if confirmedSpend {
4,036✔
367
                scriptTemplate += `
112✔
368
                        OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
112✔
369
        }
112✔
370

371
        // Close out the top level if statement.
372
        scriptTemplate += ` OP_ENDIF`
3,924✔
373

3,924✔
374
        // Use the ScriptTemplate function with the properly formatted template
3,924✔
375
        return txscript.ScriptTemplate(
3,924✔
376
                scriptTemplate,
3,924✔
377
                txscript.WithScriptTemplateParams(TemplateParams{
3,924✔
378
                        "RevKeyHash":        btcutil.Hash160(revocationKey.SerializeCompressed()), //nolint:ll
3,924✔
379
                        "ReceiverKey":       receiverHtlcKey.SerializeCompressed(),                //nolint:ll
3,924✔
380
                        "SenderKey":         senderHtlcKey.SerializeCompressed(),                  //nolint:ll
3,924✔
381
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
3,924✔
382
                }),
3,924✔
383
        )
3,924✔
384
}
385

386
// SenderHtlcSpendRevokeWithKey constructs a valid witness allowing the receiver of an
387
// HTLC to claim the output with knowledge of the revocation private key in the
388
// scenario that the sender of the HTLC broadcasts a previously revoked
389
// commitment transaction. A valid spend requires knowledge of the private key
390
// that corresponds to their revocation base point and also the private key from
391
// the per commitment point, and a valid signature under the combined public
392
// key.
393
func SenderHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
394
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
5✔
395

5✔
396
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
5✔
397
        if err != nil {
5✔
398
                return nil, err
×
399
        }
×
400

401
        // The stack required to sweep a revoke HTLC output consists simply of
402
        // the exact witness stack as one of a regular p2wkh spend. The only
403
        // difference is that the keys used were derived in an adversarial
404
        // manner in order to encode the revocation contract into a sig+key
405
        // pair.
406
        witnessStack := wire.TxWitness(make([][]byte, 3))
5✔
407
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
5✔
408
        witnessStack[1] = revokeKey.SerializeCompressed()
5✔
409
        witnessStack[2] = signDesc.WitnessScript
5✔
410

5✔
411
        return witnessStack, nil
5✔
412
}
413

414
// SenderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
415
// HTLC to claim the output with knowledge of the revocation private key in the
416
// scenario that the sender of the HTLC broadcasts a previously revoked
417
// commitment transaction.  This method first derives the appropriate revocation
418
// key, and requires that the provided SignDescriptor has a local revocation
419
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
420
// respectively.
421
func SenderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
422
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
423

4✔
424
        revokeKey, err := deriveRevokePubKey(signDesc)
4✔
425
        if err != nil {
4✔
426
                return nil, err
×
427
        }
×
428

429
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
4✔
430
}
431

432
// IsHtlcSpendRevoke is used to determine if the passed spend is spending a
433
// HTLC output using the revocation key.
434
func IsHtlcSpendRevoke(txIn *wire.TxIn, signDesc *SignDescriptor) (
435
        bool, error) {
8✔
436

8✔
437
        // For taproot channels, the revocation path only has a single witness,
8✔
438
        // as that's the key spend path.
8✔
439
        isTaproot := txscript.IsPayToTaproot(signDesc.Output.PkScript)
8✔
440
        if isTaproot {
12✔
441
                return len(txIn.Witness) == 1, nil
4✔
442
        }
4✔
443

444
        revokeKey, err := deriveRevokePubKey(signDesc)
4✔
445
        if err != nil {
4✔
446
                return false, err
×
447
        }
×
448

449
        if len(txIn.Witness) == 3 &&
4✔
450
                bytes.Equal(txIn.Witness[1], revokeKey.SerializeCompressed()) {
6✔
451

2✔
452
                return true, nil
2✔
453
        }
2✔
454

455
        return false, nil
2✔
456
}
457

458
// SenderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
459
// HTLC to redeem the pending output in the scenario that the sender broadcasts
460
// their version of the commitment transaction. A valid spend requires
461
// knowledge of the payment preimage, and a valid signature under the receivers
462
// public key.
463
func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
464
        sweepTx *wire.MsgTx, paymentPreimage []byte) (wire.TxWitness, error) {
15✔
465

15✔
466
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
15✔
467
        if err != nil {
15✔
468
                return nil, err
×
469
        }
×
470

471
        // The stack required to spend this output is simply the signature
472
        // generated above under the receiver's public key, and the payment
473
        // pre-image.
474
        witnessStack := wire.TxWitness(make([][]byte, 3))
15✔
475
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
15✔
476
        witnessStack[1] = paymentPreimage
15✔
477
        witnessStack[2] = signDesc.WitnessScript
15✔
478

15✔
479
        return witnessStack, nil
15✔
480
}
481

482
// SenderHtlcSpendTimeout constructs a valid witness allowing the sender of an
483
// HTLC to activate the time locked covenant clause of a soon to be expired
484
// HTLC.  This script simply spends the multi-sig output using the
485
// pre-generated HTLC timeout transaction.
486
func SenderHtlcSpendTimeout(receiverSig Signature,
487
        receiverSigHash txscript.SigHashType, signer Signer,
488
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (
489
        wire.TxWitness, error) {
57✔
490

57✔
491
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
57✔
492
        if err != nil {
57✔
493
                return nil, err
×
494
        }
×
495

496
        // We place a zero as the first item of the evaluated witness stack in
497
        // order to force Script execution to the HTLC timeout clause. The
498
        // second zero is required to consume the extra pop due to a bug in the
499
        // original OP_CHECKMULTISIG.
500
        witnessStack := wire.TxWitness(make([][]byte, 5))
57✔
501
        witnessStack[0] = nil
57✔
502
        witnessStack[1] = append(receiverSig.Serialize(), byte(receiverSigHash))
57✔
503
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
57✔
504
        witnessStack[3] = nil
57✔
505
        witnessStack[4] = signDesc.WitnessScript
57✔
506

57✔
507
        return witnessStack, nil
57✔
508
}
509

510
// SenderHTLCTapLeafTimeout returns the full tapscript leaf for the timeout
511
// path of the sender HTLC. This is a small script that allows the sender to
512
// timeout the HTLC after a period of time:
513
//
514
//        <local_key> OP_CHECKSIGVERIFY
515
//        <remote_key> OP_CHECKSIG
516
func SenderHTLCTapLeafTimeout(senderHtlcKey,
517
        receiverHtlcKey *btcec.PublicKey,
518
        _ ...TaprootScriptOpt) (txscript.TapLeaf, error) {
174✔
519

174✔
520
        timeoutLeafScript, err := txscript.ScriptTemplate(
174✔
521
                `
174✔
522
                {{ hex .SenderKey }} OP_CHECKSIGVERIFY
174✔
523
                {{ hex .ReceiverKey }} OP_CHECKSIG`,
174✔
524
                txscript.WithScriptTemplateParams(TemplateParams{
174✔
525
                        "SenderKey":   schnorr.SerializePubKey(senderHtlcKey),
174✔
526
                        "ReceiverKey": schnorr.SerializePubKey(receiverHtlcKey),
174✔
527
                }),
174✔
528
        )
174✔
529
        if err != nil {
174✔
530
                return txscript.TapLeaf{}, err
×
531
        }
×
532

533
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
174✔
534
}
535

536
// SenderHTLCTapLeafSuccess returns the full tapscript leaf for the success
537
// path of the sender HTLC. This is a small script that allows the receiver to
538
// redeem the HTLC with a pre-image:
539
//
540
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
541
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
542
//        <remote_htlcpubkey> OP_CHECKSIG
543
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
544
func SenderHTLCTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
545
        paymentHash []byte,
546
        opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
174✔
547

174✔
548
        opt := defaultTaprootScriptOpt()
174✔
549
        for _, o := range opts {
193✔
550
                o(opt)
19✔
551
        }
19✔
552

553
        // Check pre-image size (32 bytes), verify hash, then verify the
554
        // remote party's signature with a 1-block CSV delay.
555
        var scriptTemplate string
174✔
556
        switch {
174✔
557
        case opt.prodScript:
19✔
558
                scriptTemplate = `
19✔
559
                OP_SIZE 32 OP_EQUALVERIFY
19✔
560
                OP_HASH160 {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY
19✔
561
                {{ hex .ReceiverKey }} OP_CHECKSIGVERIFY
19✔
562
                OP_1 OP_CHECKSEQUENCEVERIFY`
19✔
563
        default:
159✔
564
                scriptTemplate = `
159✔
565
                OP_SIZE 32 OP_EQUALVERIFY
159✔
566
                OP_HASH160 {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY
159✔
567
                {{ hex .ReceiverKey }} OP_CHECKSIG
159✔
568
                OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
159✔
569
        }
570

571
        successLeafScript, err := txscript.ScriptTemplate(
174✔
572
                scriptTemplate,
174✔
573
                txscript.WithScriptTemplateParams(TemplateParams{
174✔
574
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
174✔
575
                        "ReceiverKey": schnorr.SerializePubKey(
174✔
576
                                receiverHtlcKey,
174✔
577
                        ),
174✔
578
                }),
174✔
579
        )
174✔
580
        if err != nil {
174✔
581
                return txscript.TapLeaf{}, err
×
582
        }
×
583

584
        return txscript.NewBaseTapLeaf(successLeafScript), nil
174✔
585
}
586

587
// htlcType is an enum value that denotes what type of HTLC script this is.
588
type htlcType uint8
589

590
const (
591
        // htlcLocalIncoming represents an incoming HTLC on the local
592
        // commitment transaction.
593
        htlcLocalIncoming htlcType = iota
594

595
        // htlcLocalOutgoing represents an outgoing HTLC on the local
596
        // commitment transaction.
597
        htlcLocalOutgoing
598

599
        // htlcRemoteIncoming represents an incoming HTLC on the remote
600
        // commitment transaction.
601
        htlcRemoteIncoming
602

603
        // htlcRemoteOutgoing represents an outgoing HTLC on the remote
604
        // commitment transaction.
605
        htlcRemoteOutgoing
606
)
607

608
// HtlcScriptTree holds the taproot output key, as well as the two script path
609
// leaves that every taproot HTLC script depends on.
610
type HtlcScriptTree struct {
611
        ScriptTree
612

613
        // SuccessTapLeaf is the tapleaf for the redemption path.
614
        SuccessTapLeaf txscript.TapLeaf
615

616
        // TimeoutTapLeaf is the tapleaf for the timeout path.
617
        TimeoutTapLeaf txscript.TapLeaf
618

619
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
620
        // HTLC script tree with new spend paths, or just as extra commitment
621
        // space. When present, this leaf will always be in the right-most area
622
        // of the tapscript tree.
623
        AuxLeaf AuxTapLeaf
624

625
        // htlcType is the type of HTLC script this is.
626
        htlcType htlcType
627
}
628

629
// WitnessScriptToSign returns the witness script that we'll use when signing
630
// for the remote party, and also verifying signatures on our transactions. As
631
// an example, when we create an outgoing HTLC for the remote party, we want to
632
// sign the success path for them, so we'll return the success path leaf.
633
func (h *HtlcScriptTree) WitnessScriptToSign() []byte {
287✔
634
        switch h.htlcType {
287✔
635
        // For incoming HLTCs on our local commitment, we care about verifying
636
        // the success path.
637
        case htlcLocalIncoming:
69✔
638
                return h.SuccessTapLeaf.Script
69✔
639

640
        // For incoming HTLCs on the remote party's commitment, we want to sign
641
        // the timeout path for them.
642
        case htlcRemoteIncoming:
81✔
643
                return h.TimeoutTapLeaf.Script
81✔
644

645
        // For outgoing HTLCs on our local commitment, we want to verify the
646
        // timeout path.
647
        case htlcLocalOutgoing:
75✔
648
                return h.TimeoutTapLeaf.Script
75✔
649

650
        // For outgoing HTLCs on the remote party's commitment, we want to sign
651
        // the success path for them.
652
        case htlcRemoteOutgoing:
74✔
653
                return h.SuccessTapLeaf.Script
74✔
654

655
        default:
×
656
                panic(fmt.Sprintf("unknown htlc type: %v", h.htlcType))
×
657
        }
658
}
659

660
// WitnessScriptForPath returns the witness script for the given spending path.
661
// An error is returned if the path is unknown.
662
func (h *HtlcScriptTree) WitnessScriptForPath(path ScriptPath) ([]byte, error) {
19✔
663
        switch path {
19✔
664
        case ScriptPathSuccess:
12✔
665
                return h.SuccessTapLeaf.Script, nil
12✔
666
        case ScriptPathTimeout:
11✔
667
                return h.TimeoutTapLeaf.Script, nil
11✔
668
        default:
×
669
                return nil, fmt.Errorf("unknown script path: %v", path)
×
670
        }
671
}
672

673
// CtrlBlockForPath returns the control block for the given spending path. For
674
// script types that don't have a control block, nil is returned.
675
func (h *HtlcScriptTree) CtrlBlockForPath(
676
        path ScriptPath) (*txscript.ControlBlock, error) {
4✔
677

4✔
678
        switch path {
4✔
679
        case ScriptPathSuccess:
4✔
680
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
681
                        h.SuccessTapLeaf.Script, h.InternalKey,
4✔
682
                        h.TapscriptTree,
4✔
683
                )), nil
4✔
684
        case ScriptPathTimeout:
4✔
685
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
686
                        h.TimeoutTapLeaf.Script, h.InternalKey,
4✔
687
                        h.TapscriptTree,
4✔
688
                )), nil
4✔
689
        default:
×
690
                return nil, fmt.Errorf("unknown script path: %v", path)
×
691
        }
692
}
693

694
// Tree returns the underlying ScriptTree of the HtlcScriptTree.
695
func (h *HtlcScriptTree) Tree() ScriptTree {
×
696
        return h.ScriptTree
×
697
}
×
698

699
// A compile time check to ensure HtlcScriptTree implements the
700
// TapscriptMultiplexer interface.
701
var _ TapscriptDescriptor = (*HtlcScriptTree)(nil)
702

703
// senderHtlcTapScriptTree builds the tapscript tree which is used to anchor
704
// the HTLC key for HTLCs on the sender's commitment.
705
func senderHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
706
        revokeKey *btcec.PublicKey, payHash []byte, hType htlcType,
707
        auxLeaf AuxTapLeaf,
708
        opts ...TaprootScriptOpt) (*HtlcScriptTree, error) {
173✔
709

173✔
710
        // First, we'll obtain the tap leaves for both the success and timeout
173✔
711
        // path.
173✔
712
        successTapLeaf, err := SenderHTLCTapLeafSuccess(
173✔
713
                receiverHtlcKey, payHash, opts...,
173✔
714
        )
173✔
715
        if err != nil {
173✔
716
                return nil, err
×
717
        }
×
718
        timeoutTapLeaf, err := SenderHTLCTapLeafTimeout(
173✔
719
                senderHtlcKey, receiverHtlcKey, opts...,
173✔
720
        )
173✔
721
        if err != nil {
173✔
722
                return nil, err
×
723
        }
×
724

725
        tapLeaves := []txscript.TapLeaf{successTapLeaf, timeoutTapLeaf}
173✔
726
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
175✔
727
                tapLeaves = append(tapLeaves, l)
2✔
728
        })
2✔
729

730
        // With the two leaves obtained, we'll now make the tapscript tree,
731
        // then obtain the root from that
732
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
173✔
733

173✔
734
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
173✔
735

173✔
736
        // With the tapscript root obtained, we'll tweak the revocation key
173✔
737
        // with this value to obtain the key that HTLCs will be sent to.
173✔
738
        htlcKey := txscript.ComputeTaprootOutputKey(
173✔
739
                revokeKey, tapScriptRoot[:],
173✔
740
        )
173✔
741

173✔
742
        return &HtlcScriptTree{
173✔
743
                ScriptTree: ScriptTree{
173✔
744
                        TaprootKey:    htlcKey,
173✔
745
                        TapscriptTree: tapscriptTree,
173✔
746
                        TapscriptRoot: tapScriptRoot[:],
173✔
747
                        InternalKey:   revokeKey,
173✔
748
                },
173✔
749
                SuccessTapLeaf: successTapLeaf,
173✔
750
                TimeoutTapLeaf: timeoutTapLeaf,
173✔
751
                AuxLeaf:        auxLeaf,
173✔
752
                htlcType:       hType,
173✔
753
        }, nil
173✔
754
}
755

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

169✔
789
        var hType htlcType
169✔
790
        if whoseCommit.IsLocal() {
254✔
791
                hType = htlcLocalOutgoing
85✔
792
        } else {
173✔
793
                hType = htlcRemoteIncoming
88✔
794
        }
88✔
795

796
        // Given all the necessary parameters, we'll return the HTLC script
797
        // tree that includes the top level output script, as well as the two
798
        // tap leaf paths.
799
        return senderHtlcTapScriptTree(
169✔
800
                senderHtlcKey, receiverHtlcKey, revokeKey, payHash, hType,
169✔
801
                auxLeaf, opts...,
169✔
802
        )
169✔
803
}
804

805
// maybeAppendSighashType appends a sighash type to the end of a signature if
806
// the sighash type isn't sighash default.
807
func maybeAppendSighash(sig Signature, sigHash txscript.SigHashType) []byte {
1,685✔
808
        sigBytes := sig.Serialize()
1,685✔
809
        if sigHash == txscript.SigHashDefault {
3,148✔
810
                return sigBytes
1,463✔
811
        }
1,463✔
812

813
        return append(sigBytes, byte(sigHash))
226✔
814
}
815

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

21✔
824
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
21✔
825
        if err != nil {
21✔
826
                return nil, err
×
827
        }
×
828

829
        // In addition to the signature and the witness/leaf script, we also
830
        // need to make a control block proof using the tapscript tree.
831
        var ctrlBlock []byte
21✔
832
        if signDesc.ControlBlock == nil {
38✔
833
                successControlBlock := MakeTaprootCtrlBlock(
17✔
834
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
17✔
835
                )
17✔
836

17✔
837
                ctrlBytes, err := successControlBlock.ToBytes()
17✔
838
                if err != nil {
17✔
839
                        return nil, err
×
840
                }
×
841

842
                ctrlBlock = ctrlBytes
17✔
843
        } else {
4✔
844
                ctrlBlock = signDesc.ControlBlock
4✔
845
        }
4✔
846

847
        // The final witness stack is:
848
        //  <receiver sig> <preimage> <success_script> <control_block>
849
        witnessStack := make(wire.TxWitness, 4)
21✔
850
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
21✔
851
        witnessStack[1] = preimage
21✔
852
        witnessStack[2] = signDesc.WitnessScript
21✔
853
        witnessStack[3] = ctrlBlock
21✔
854

21✔
855
        return witnessStack, nil
21✔
856
}
857

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

33✔
868
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
33✔
869
        if err != nil {
33✔
870
                return nil, err
×
871
        }
×
872

873
        // With the sweep signature obtained, we'll obtain the control block
874
        // proof needed to perform a valid spend for the timeout path.
875
        var ctrlBlockBytes []byte
33✔
876
        if signDesc.ControlBlock == nil {
66✔
877
                timeoutControlBlock := MakeTaprootCtrlBlock(
33✔
878
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
33✔
879
                )
33✔
880
                ctrlBytes, err := timeoutControlBlock.ToBytes()
33✔
881
                if err != nil {
33✔
882
                        return nil, err
×
883
                }
×
884

885
                ctrlBlockBytes = ctrlBytes
33✔
886
        } else {
4✔
887
                ctrlBlockBytes = signDesc.ControlBlock
4✔
888
        }
4✔
889

890
        // The final witness stack is:
891
        //  <receiver sig> <local sig> <timeout_script> <control_block>
892
        witnessStack := make(wire.TxWitness, 4)
33✔
893
        witnessStack[0] = maybeAppendSighash(receiverSig, receiverSigHash)
33✔
894
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
33✔
895
        witnessStack[2] = signDesc.WitnessScript
33✔
896
        witnessStack[3] = ctrlBlockBytes
33✔
897

33✔
898
        return witnessStack, nil
33✔
899
}
900

901
// SenderHTLCScriptTaprootRevoke creates a valid witness needed to spend the
902
// revocation path of the HTLC. This uses a plain keyspend using the specified
903
// revocation key.
904
func SenderHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
905
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
21✔
906

21✔
907
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
21✔
908
        if err != nil {
21✔
909
                return nil, err
×
910
        }
×
911

912
        // The witness stack in this case is pretty simple: we only need to
913
        // specify the signature generated.
914
        witnessStack := make(wire.TxWitness, 1)
21✔
915
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
21✔
916

21✔
917
        return witnessStack, nil
21✔
918
}
919

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

4,363✔
961
        // The script structure mirrors SenderHTLCScript but from the
4,363✔
962
        // receiver's perspective:
4,363✔
963
        //   - Revocation path: DUP+HASH160 check, then checksig.
4,363✔
964
        //   - Else: push sender key, swap, check size.
4,363✔
965
        //     - If 32 bytes (preimage path): hash160-verify the preimage,
4,363✔
966
        //       then 2-of-2 multisig with sender+receiver keys.
4,363✔
967
        //     - If not 32 bytes (timeout path): drop, CLTV check, checksig.
4,363✔
968
        //   - Optional 1-block CSV for confirmed spend.
4,363✔
969
        scriptTemplate := `
4,363✔
970
                OP_DUP OP_HASH160 {{ hex .RevKeyHash }} OP_EQUAL
4,363✔
971
                OP_IF
4,363✔
972
                        OP_CHECKSIG
4,363✔
973
                OP_ELSE
4,363✔
974
                        {{ hex .SenderKey }}
4,363✔
975
                        OP_SWAP
4,363✔
976
                        OP_SIZE 32 OP_EQUAL
4,363✔
977
                        OP_IF
4,363✔
978
                                OP_HASH160 {{ hex .PaymentHashRipemd }}
4,363✔
979
                                OP_EQUALVERIFY
4,363✔
980
                                OP_2 OP_SWAP {{ hex .ReceiverKey }}
4,363✔
981
                                OP_2 OP_CHECKMULTISIG
4,363✔
982
                        OP_ELSE
4,363✔
983
                                OP_DROP
4,363✔
984
                                {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY
4,363✔
985
                                OP_DROP OP_CHECKSIG
4,363✔
986
                        OP_ENDIF
4,363✔
987
        `
4,363✔
988

4,363✔
989
        // Add 1 block CSV delay for non-revocation clauses if confirmation is
4,363✔
990
        // required.
4,363✔
991
        if confirmedSpend {
4,516✔
992
                scriptTemplate += `
153✔
993
                        OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
153✔
994
        }
153✔
995

996
        // Close out the outer if statement.
997
        scriptTemplate += ` OP_ENDIF`
4,363✔
998

4,363✔
999
        // Use the ScriptTemplate function with the properly formatted template
4,363✔
1000
        return txscript.ScriptTemplate(
4,363✔
1001
                scriptTemplate,
4,363✔
1002
                txscript.WithScriptTemplateParams(TemplateParams{
4,363✔
1003
                        "RevKeyHash": btcutil.Hash160(
4,363✔
1004
                                revocationKey.SerializeCompressed(),
4,363✔
1005
                        ),
4,363✔
1006
                        "SenderKey":         senderHtlcKey.SerializeCompressed(),   //nolint:ll
4,363✔
1007
                        "ReceiverKey":       receiverHtlcKey.SerializeCompressed(), //nolint:ll
4,363✔
1008
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
4,363✔
1009
                        "CltvExpiry":        int64(cltvExpiry),
4,363✔
1010
                }),
4,363✔
1011
        )
4,363✔
1012
}
1013

1014
// ReceiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
1015
// an HTLC to redeem the conditional payment in the event that their commitment
1016
// transaction is broadcast. This clause transitions the state of the HLTC
1017
// output into the delay+claim state by activating the off-chain covenant bound
1018
// by the 2-of-2 multi-sig output. The HTLC success timeout transaction being
1019
// signed has a relative timelock delay enforced by its sequence number. This
1020
// delay give the sender of the HTLC enough time to revoke the output if this
1021
// is a breach commitment transaction.
1022
func ReceiverHtlcSpendRedeem(senderSig Signature,
1023
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1024
        signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
1025
        wire.TxWitness, error) {
62✔
1026

62✔
1027
        // First, we'll generate a signature for the HTLC success transaction.
62✔
1028
        // The signDesc should be signing with the public key used as the
62✔
1029
        // receiver's public key and also the correct single tweak.
62✔
1030
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
62✔
1031
        if err != nil {
62✔
1032
                return nil, err
×
1033
        }
×
1034

1035
        // The final witness stack is used the provide the script with the
1036
        // payment pre-image, and also execute the multi-sig clause after the
1037
        // pre-images matches. We add a nil item at the bottom of the stack in
1038
        // order to consume the extra pop within OP_CHECKMULTISIG.
1039
        witnessStack := wire.TxWitness(make([][]byte, 5))
62✔
1040
        witnessStack[0] = nil
62✔
1041
        witnessStack[1] = append(senderSig.Serialize(), byte(senderSigHash))
62✔
1042
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
62✔
1043
        witnessStack[3] = paymentPreimage
62✔
1044
        witnessStack[4] = signDesc.WitnessScript
62✔
1045

62✔
1046
        return witnessStack, nil
62✔
1047
}
1048

1049
// ReceiverHtlcSpendRevokeWithKey constructs a valid witness allowing the sender of an
1050
// HTLC within a previously revoked commitment transaction to re-claim the
1051
// pending funds in the case that the receiver broadcasts this revoked
1052
// commitment transaction.
1053
func ReceiverHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
1054
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
20✔
1055

20✔
1056
        // First, we'll generate a signature for the sweep transaction.  The
20✔
1057
        // signDesc should be signing with the public key used as the fully
20✔
1058
        // derived revocation public key and also the correct double tweak
20✔
1059
        // value.
20✔
1060
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
20✔
1061
        if err != nil {
20✔
1062
                return nil, err
×
1063
        }
×
1064

1065
        // We place a zero, then one as the first items in the evaluated
1066
        // witness stack in order to force script execution to the HTLC
1067
        // revocation clause.
1068
        witnessStack := wire.TxWitness(make([][]byte, 3))
20✔
1069
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
20✔
1070
        witnessStack[1] = revokeKey.SerializeCompressed()
20✔
1071
        witnessStack[2] = signDesc.WitnessScript
20✔
1072

20✔
1073
        return witnessStack, nil
20✔
1074
}
1075

1076
func deriveRevokePubKey(signDesc *SignDescriptor) (*btcec.PublicKey, error) {
27✔
1077
        if signDesc.KeyDesc.PubKey == nil {
27✔
1078
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
1079
                        "KeyDesc pubkey")
×
1080
        }
×
1081

1082
        // Derive the revocation key using the local revocation base point and
1083
        // commitment point.
1084
        revokeKey := DeriveRevocationPubkey(
27✔
1085
                signDesc.KeyDesc.PubKey,
27✔
1086
                signDesc.DoubleTweak.PubKey(),
27✔
1087
        )
27✔
1088

27✔
1089
        return revokeKey, nil
27✔
1090
}
1091

1092
// ReceiverHtlcSpendRevoke constructs a valid witness allowing the sender of an
1093
// HTLC within a previously revoked commitment transaction to re-claim the
1094
// pending funds in the case that the receiver broadcasts this revoked
1095
// commitment transaction. This method first derives the appropriate revocation
1096
// key, and requires that the provided SignDescriptor has a local revocation
1097
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
1098
// respectively.
1099
func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1100
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
19✔
1101

19✔
1102
        revokeKey, err := deriveRevokePubKey(signDesc)
19✔
1103
        if err != nil {
19✔
1104
                return nil, err
×
1105
        }
×
1106

1107
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
19✔
1108
}
1109

1110
// ReceiverHtlcSpendTimeout constructs a valid witness allowing the sender of
1111
// an HTLC to recover the pending funds after an absolute timeout in the
1112
// scenario that the receiver of the HTLC broadcasts their version of the
1113
// commitment transaction. If the caller has already set the lock time on the
1114
// spending transaction, than a value of -1 can be passed for the cltvExpiry
1115
// value.
1116
//
1117
// NOTE: The target input of the passed transaction MUST NOT have a final
1118
// sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
1119
func ReceiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
1120
        sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) {
12✔
1121

12✔
1122
        // If the caller set a proper timeout value, then we'll apply it
12✔
1123
        // directly to the transaction.
12✔
1124
        if cltvExpiry != -1 {
20✔
1125
                // The HTLC output has an absolute time period before we are
8✔
1126
                // permitted to recover the pending funds. Therefore we need to
8✔
1127
                // set the locktime on this sweeping transaction in order to
8✔
1128
                // pass Script verification.
8✔
1129
                sweepTx.LockTime = uint32(cltvExpiry)
8✔
1130
        }
8✔
1131

1132
        // With the lock time on the transaction set, we'll not generate a
1133
        // signature for the sweep transaction. The passed sign descriptor
1134
        // should be created using the raw public key of the sender (w/o the
1135
        // single tweak applied), and the single tweak set to the proper value
1136
        // taking into account the current state's point.
1137
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
12✔
1138
        if err != nil {
12✔
1139
                return nil, err
×
1140
        }
×
1141

1142
        witnessStack := wire.TxWitness(make([][]byte, 3))
12✔
1143
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
12✔
1144
        witnessStack[1] = nil
12✔
1145
        witnessStack[2] = signDesc.WitnessScript
12✔
1146

12✔
1147
        return witnessStack, nil
12✔
1148
}
1149

1150
// ReceiverHtlcTapLeafTimeout returns the full tapscript leaf for the timeout
1151
// path of the sender HTLC. This is a small script that allows the sender
1152
// timeout the HTLC after expiry:
1153
//
1154
//        <sender_htlcpubkey> OP_CHECKSIG
1155
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
1156
//        <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1157
func ReceiverHtlcTapLeafTimeout(senderHtlcKey *btcec.PublicKey,
1158
        cltvExpiry uint32, opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
162✔
1159

162✔
1160
        opt := defaultTaprootScriptOpt()
162✔
1161
        for _, o := range opts {
190✔
1162
                o(opt)
28✔
1163
        }
28✔
1164

1165
        // Verify sender signature, enforce 1-block CSV, then verify CLTV
1166
        // expiry. The prod script variant uses CHECKSIGVERIFY/VERIFY instead
1167
        // of CHECKSIG+DROP patterns.
1168
        var scriptTemplate string
162✔
1169
        switch {
162✔
1170
        case opt.prodScript:
28✔
1171
                scriptTemplate = `
28✔
1172
                {{ hex .SenderKey }} OP_CHECKSIGVERIFY
28✔
1173
                OP_1 OP_CHECKSEQUENCEVERIFY OP_VERIFY
28✔
1174
                {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY`
28✔
1175
        default:
138✔
1176
                scriptTemplate = `
138✔
1177
                {{ hex .SenderKey }} OP_CHECKSIG
138✔
1178
                OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP
138✔
1179
                {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP`
138✔
1180
        }
1181

1182
        timeoutLeafScript, err := txscript.ScriptTemplate(
162✔
1183
                scriptTemplate,
162✔
1184
                txscript.WithScriptTemplateParams(TemplateParams{
162✔
1185
                        "SenderKey":  schnorr.SerializePubKey(senderHtlcKey),
162✔
1186
                        "CltvExpiry": int64(cltvExpiry),
162✔
1187
                }),
162✔
1188
        )
162✔
1189
        if err != nil {
162✔
1190
                return txscript.TapLeaf{}, err
×
1191
        }
×
1192

1193
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
162✔
1194
}
1195

1196
// ReceiverHtlcTapLeafSuccess returns the full tapscript leaf for the success
1197
// path for an HTLC on the receiver's commitment transaction. This script
1198
// allows the receiver to redeem an HTLC with knowledge of the preimage:
1199
//
1200
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
1201
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1202
//        <receiver_htlcpubkey> OP_CHECKSIGVERIFY
1203
//        <sender_htlcpubkey> OP_CHECKSIG
1204
func ReceiverHtlcTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
1205
        senderHtlcKey *btcec.PublicKey,
1206
        paymentHash []byte,
1207
        _ ...TaprootScriptOpt) (txscript.TapLeaf, error) {
162✔
1208

162✔
1209
        successLeafScript, err := txscript.ScriptTemplate(
162✔
1210
                `
162✔
1211
                OP_SIZE 32 OP_EQUALVERIFY
162✔
1212
                OP_HASH160 {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY
162✔
1213
                {{ hex .ReceiverKey }} OP_CHECKSIGVERIFY
162✔
1214
                {{ hex .SenderKey }} OP_CHECKSIG`,
162✔
1215
                txscript.WithScriptTemplateParams(TemplateParams{
162✔
1216
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
162✔
1217
                        "ReceiverKey": schnorr.SerializePubKey(
162✔
1218
                                receiverHtlcKey,
162✔
1219
                        ),
162✔
1220
                        "SenderKey": schnorr.SerializePubKey(senderHtlcKey),
162✔
1221
                }),
162✔
1222
        )
162✔
1223
        if err != nil {
162✔
1224
                return txscript.TapLeaf{}, err
×
1225
        }
×
1226

1227
        return txscript.NewBaseTapLeaf(successLeafScript), nil
162✔
1228
}
1229

1230
// receiverHtlcTapScriptTree builds the tapscript tree which is used to anchor
1231
// the HTLC key for HTLCs on the receiver's commitment.
1232
func receiverHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
1233
        revokeKey *btcec.PublicKey, payHash []byte, cltvExpiry uint32,
1234
        hType htlcType, auxLeaf AuxTapLeaf,
1235
        opts ...TaprootScriptOpt) (*HtlcScriptTree, error) {
161✔
1236

161✔
1237
        // First, we'll obtain the tap leaves for both the success and timeout
161✔
1238
        // path.
161✔
1239
        successTapLeaf, err := ReceiverHtlcTapLeafSuccess(
161✔
1240
                receiverHtlcKey, senderHtlcKey, payHash, opts...,
161✔
1241
        )
161✔
1242
        if err != nil {
161✔
1243
                return nil, err
×
1244
        }
×
1245
        timeoutTapLeaf, err := ReceiverHtlcTapLeafTimeout(
161✔
1246
                senderHtlcKey, cltvExpiry, opts...,
161✔
1247
        )
161✔
1248
        if err != nil {
161✔
1249
                return nil, err
×
1250
        }
×
1251

1252
        tapLeaves := []txscript.TapLeaf{timeoutTapLeaf, successTapLeaf}
161✔
1253
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
163✔
1254
                tapLeaves = append(tapLeaves, l)
2✔
1255
        })
2✔
1256

1257
        // With the two leaves obtained, we'll now make the tapscript tree,
1258
        // then obtain the root from that
1259
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
161✔
1260

161✔
1261
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
161✔
1262

161✔
1263
        // With the tapscript root obtained, we'll tweak the revocation key
161✔
1264
        // with this value to obtain the key that HTLCs will be sent to.
161✔
1265
        htlcKey := txscript.ComputeTaprootOutputKey(
161✔
1266
                revokeKey, tapScriptRoot[:],
161✔
1267
        )
161✔
1268

161✔
1269
        return &HtlcScriptTree{
161✔
1270
                ScriptTree: ScriptTree{
161✔
1271
                        TaprootKey:    htlcKey,
161✔
1272
                        TapscriptTree: tapscriptTree,
161✔
1273
                        TapscriptRoot: tapScriptRoot[:],
161✔
1274
                        InternalKey:   revokeKey,
161✔
1275
                },
161✔
1276
                SuccessTapLeaf: successTapLeaf,
161✔
1277
                TimeoutTapLeaf: timeoutTapLeaf,
161✔
1278
                AuxLeaf:        auxLeaf,
161✔
1279
                htlcType:       hType,
161✔
1280
        }, nil
161✔
1281
}
1282

1283
// ReceiverHTLCScriptTaproot constructs the taproot witness program (schnor
1284
// key) for an incoming HTLC on the receiver's version of the commitment
1285
// transaction. This method returns the top level tweaked public key that
1286
// commits to both the script paths. From the PoV of the receiver, this is an
1287
// accepted HTLC.
1288
//
1289
// The returned key commits to a tapscript tree with two possible paths:
1290
//
1291
//   - The timeout path:
1292
//     <remote_htlcpubkey> OP_CHECKSIG
1293
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
1294
//     <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1295
//
1296
//   - Success path:
1297
//     OP_SIZE 32 OP_EQUALVERIFY
1298
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1299
//     <local_htlcpubkey> OP_CHECKSIGVERIFY
1300
//     <remote_htlcpubkey> OP_CHECKSIG
1301
//
1302
// The timeout path can be spent with a witness of:
1303
//   - <sender sig> <timeout_script> <control_block>
1304
//
1305
// The success path can be spent with a witness of:
1306
//   - <sender sig> <receiver sig> <preimage> <success_script> <control_block>
1307
//
1308
// The top level keyspend key is the revocation key, which allows a defender to
1309
// unilaterally spend the created output. Both the final output key as well as
1310
// the tap leaf are returned.
1311
func ReceiverHTLCScriptTaproot(cltvExpiry uint32,
1312
        senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey,
1313
        payHash []byte, whoseCommit lntypes.ChannelParty,
1314
        auxLeaf AuxTapLeaf, opts ...TaprootScriptOpt) (*HtlcScriptTree, error) {
157✔
1315

157✔
1316
        var hType htlcType
157✔
1317
        if whoseCommit.IsLocal() {
237✔
1318
                hType = htlcLocalIncoming
80✔
1319
        } else {
161✔
1320
                hType = htlcRemoteOutgoing
81✔
1321
        }
81✔
1322

1323
        // Given all the necessary parameters, we'll return the HTLC script
1324
        // tree that includes the top level output script, as well as the two
1325
        // tap leaf paths.
1326
        return receiverHtlcTapScriptTree(
157✔
1327
                senderHtlcKey, receiverHtlcKey, revocationKey, payHash,
157✔
1328
                cltvExpiry, hType, auxLeaf, opts...,
157✔
1329
        )
157✔
1330
}
1331

1332
// ReceiverHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
1333
// receiver taproot HTLC with the pre-image. The returned witness is valid and
1334
// includes the control block required to spend the output.
1335
func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
1336
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1337
        signer Signer, signDesc *SignDescriptor,
1338
        htlcSuccessTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1339
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
42✔
1340

42✔
1341
        // First, we'll generate a signature for the HTLC success transaction.
42✔
1342
        // The signDesc should be signing with the public key used as the
42✔
1343
        // receiver's public key and also the correct single tweak.
42✔
1344
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
42✔
1345
        if err != nil {
42✔
1346
                return nil, err
×
1347
        }
×
1348

1349
        // In addition to the signature and the witness/leaf script, we also
1350
        // need to make a control block proof using the tapscript tree.
1351
        var ctrlBlock []byte
42✔
1352
        if signDesc.ControlBlock == nil {
84✔
1353
                redeemControlBlock := MakeTaprootCtrlBlock(
42✔
1354
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
42✔
1355
                )
42✔
1356
                ctrlBytes, err := redeemControlBlock.ToBytes()
42✔
1357
                if err != nil {
42✔
1358
                        return nil, err
×
1359
                }
×
1360

1361
                ctrlBlock = ctrlBytes
42✔
1362
        } else {
4✔
1363
                ctrlBlock = signDesc.ControlBlock
4✔
1364
        }
4✔
1365

1366
        // The final witness stack is:
1367
        //  * <sender sig> <receiver sig> <preimage> <success_script>
1368
        //    <control_block>
1369
        witnessStack := wire.TxWitness(make([][]byte, 5))
42✔
1370
        witnessStack[0] = maybeAppendSighash(senderSig, senderSigHash)
42✔
1371
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
42✔
1372
        witnessStack[2] = paymentPreimage
42✔
1373
        witnessStack[3] = signDesc.WitnessScript
42✔
1374
        witnessStack[4] = ctrlBlock
42✔
1375

42✔
1376
        return witnessStack, nil
42✔
1377
}
1378

1379
// ReceiverHTLCScriptTaprootTimeout creates a valid witness needed to timeout
1380
// an HTLC on the receiver's commitment transaction after the timeout has
1381
// elapsed.
1382
func ReceiverHTLCScriptTaprootTimeout(signer Signer, signDesc *SignDescriptor,
1383
        sweepTx *wire.MsgTx, cltvExpiry int32, revokeKey *btcec.PublicKey,
1384
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
29✔
1385

29✔
1386
        // If the caller set a proper timeout value, then we'll apply it
29✔
1387
        // directly to the transaction.
29✔
1388
        //
29✔
1389
        // TODO(roasbeef): helper func
29✔
1390
        if cltvExpiry != -1 {
54✔
1391
                // The HTLC output has an absolute time period before we are
25✔
1392
                // permitted to recover the pending funds. Therefore we need to
25✔
1393
                // set the locktime on this sweeping transaction in order to
25✔
1394
                // pass Script verification.
25✔
1395
                sweepTx.LockTime = uint32(cltvExpiry)
25✔
1396
        }
25✔
1397

1398
        // With the lock time on the transaction set, we'll now generate a
1399
        // signature for the sweep transaction. The passed sign descriptor
1400
        // should be created using the raw public key of the sender (w/o the
1401
        // single tweak applied), and the single tweak set to the proper value
1402
        // taking into account the current state's point.
1403
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
29✔
1404
        if err != nil {
29✔
1405
                return nil, err
×
1406
        }
×
1407

1408
        // In addition to the signature and the witness/leaf script, we also
1409
        // need to make a control block proof using the tapscript tree.
1410
        var ctrlBlock []byte
29✔
1411
        if signDesc.ControlBlock == nil {
54✔
1412
                timeoutControlBlock := MakeTaprootCtrlBlock(
25✔
1413
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
25✔
1414
                )
25✔
1415
                ctrlBlock, err = timeoutControlBlock.ToBytes()
25✔
1416
                if err != nil {
25✔
1417
                        return nil, err
×
1418
                }
×
1419
        } else {
4✔
1420
                ctrlBlock = signDesc.ControlBlock
4✔
1421
        }
4✔
1422

1423
        // The final witness is pretty simple, we just need to present a valid
1424
        // signature for the script, and then provide the control block.
1425
        witnessStack := make(wire.TxWitness, 3)
29✔
1426
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
29✔
1427
        witnessStack[1] = signDesc.WitnessScript
29✔
1428
        witnessStack[2] = ctrlBlock
29✔
1429

29✔
1430
        return witnessStack, nil
29✔
1431
}
1432

1433
// ReceiverHTLCScriptTaprootRevoke creates a valid witness needed to spend the
1434
// revocation path of the HTLC from the PoV of the sender (offerer) of the
1435
// HTLC. This uses a plain keyspend using the specified revocation key.
1436
func ReceiverHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
1437
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
13✔
1438

13✔
1439
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
13✔
1440
        if err != nil {
13✔
1441
                return nil, err
×
1442
        }
×
1443

1444
        // The witness stack in this case is pretty simple: we only need to
1445
        // specify the signature generated.
1446
        witnessStack := make(wire.TxWitness, 1)
13✔
1447
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
13✔
1448

13✔
1449
        return witnessStack, nil
13✔
1450
}
1451

1452
// SecondLevelHtlcScript is the uniform script that's used as the output for
1453
// the second-level HTLC transactions. The second level transaction act as a
1454
// sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1455
// spent in a particular way, and to a particular output.
1456
//
1457
// Possible Input Scripts:
1458
//
1459
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1460
//     state:
1461
//     <revoke sig> 1
1462
//
1463
//   - To claim and HTLC output, either with a pre-image or due to a timeout:
1464
//     <delay sig> 0
1465
//
1466
// Output Script:
1467
//
1468
//         OP_IF
1469
//                <revoke key>
1470
//         OP_ELSE
1471
//                <delay in blocks>
1472
//                OP_CHECKSEQUENCEVERIFY
1473
//                OP_DROP
1474
//                <delay key>
1475
//         OP_ENDIF
1476
//         OP_CHECKSIG
1477
//
1478
// TODO(roasbeef): possible renames for second-level
1479
//   - transition?
1480
//   - covenant output
1481
func SecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1482
        csvDelay uint32) ([]byte, error) {
7,932✔
1483

7,932✔
1484
        // In either case, we'll ensure that only either the party possessing
7,932✔
1485
        // the revocation private key, or the delay private key is able to
7,932✔
1486
        // spend this output.
7,932✔
1487
        return txscript.ScriptTemplate(
7,932✔
1488
                `
7,932✔
1489
                OP_IF
7,932✔
1490
                        {{ hex .RevokeKey }}
7,932✔
1491
                OP_ELSE
7,932✔
1492
                        {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP
7,932✔
1493
                        {{ hex .DelayKey }}
7,932✔
1494
                OP_ENDIF OP_CHECKSIG`,
7,932✔
1495
                txscript.WithScriptTemplateParams(TemplateParams{
7,932✔
1496
                        "RevokeKey": revocationKey.SerializeCompressed(),
7,932✔
1497
                        "CsvDelay":  int64(csvDelay),
7,932✔
1498
                        "DelayKey":  delayKey.SerializeCompressed(),
7,932✔
1499
                }),
7,932✔
1500
        )
7,932✔
1501
}
7,932✔
1502

1503
// TODO(roasbeef): move all taproot stuff to new file?
1504

1505
// TaprootSecondLevelTapLeaf constructs the tap leaf used as the sole script
1506
// path for a second level HTLC spend.
1507
//
1508
// The final script used is:
1509
//
1510
//        <local_delay_key> OP_CHECKSIG
1511
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1512
func TaprootSecondLevelTapLeaf(delayKey *btcec.PublicKey,
1513
        csvDelay uint32, opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
260✔
1514

260✔
1515
        opt := defaultTaprootScriptOpt()
260✔
1516
        for _, o := range opts {
302✔
1517
                o(opt)
42✔
1518
        }
42✔
1519

1520
        // Ensure the proper party can sign for this output.
1521
        // Assuming the above passes, then we'll now ensure that the CSV delay
1522
        // has been upheld, dropping the int we pushed on. If the sig above is
1523
        // valid, then a 1 will be left on the stack.
1524
        var scriptTemplate string
260✔
1525
        switch {
260✔
1526
        case opt.prodScript:
42✔
1527
                scriptTemplate = `
42✔
1528
                {{ hex .DelayKey }} OP_CHECKSIGVERIFY
42✔
1529
                {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY`
42✔
1530
        default:
222✔
1531
                scriptTemplate = `
222✔
1532
                {{ hex .DelayKey }} OP_CHECKSIG
222✔
1533
                {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP`
222✔
1534
        }
1535

1536
        secondLevelLeafScript, err := txscript.ScriptTemplate(
260✔
1537
                scriptTemplate,
260✔
1538
                txscript.WithScriptTemplateParams(TemplateParams{
260✔
1539
                        "DelayKey": schnorr.SerializePubKey(delayKey),
260✔
1540
                        "CsvDelay": int64(csvDelay),
260✔
1541
                }),
260✔
1542
        )
260✔
1543
        if err != nil {
260✔
1544
                return txscript.TapLeaf{}, err
×
1545
        }
×
1546

1547
        return txscript.NewBaseTapLeaf(secondLevelLeafScript), nil
260✔
1548
}
1549

1550
// SecondLevelHtlcTapscriptTree construct the indexed tapscript tree needed to
1551
// generate the tap tweak to create the final output and also control block.
1552
func SecondLevelHtlcTapscriptTree(delayKey *btcec.PublicKey,
1553
        csvDelay uint32, auxLeaf AuxTapLeaf,
1554
        opts ...TaprootScriptOpt) (*txscript.IndexedTapScriptTree, error) {
259✔
1555

259✔
1556
        // First grab the second level leaf script we need to create the top
259✔
1557
        // level output.
259✔
1558
        secondLevelTapLeaf, err := TaprootSecondLevelTapLeaf(
259✔
1559
                delayKey, csvDelay, opts...,
259✔
1560
        )
259✔
1561
        if err != nil {
259✔
1562
                return nil, err
×
1563
        }
×
1564

1565
        tapLeaves := []txscript.TapLeaf{secondLevelTapLeaf}
259✔
1566
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
261✔
1567
                tapLeaves = append(tapLeaves, l)
2✔
1568
        })
2✔
1569

1570
        // Now that we have the sole second level script, we can create the
1571
        // tapscript tree that commits to both the leaves.
1572
        return txscript.AssembleTaprootScriptTree(tapLeaves...), nil
259✔
1573
}
1574

1575
// TaprootSecondLevelHtlcScript is the uniform script that's used as the output
1576
// for the second-level HTLC transaction. The second level transaction acts as
1577
// an off-chain 2-of-2 covenant that can only be spent a particular way and to
1578
// a particular output.
1579
//
1580
// Possible Input Scripts:
1581
//   - revocation sig
1582
//   - <local_delay_sig>
1583
//
1584
// The script main script lets the broadcaster spend after a delay the script
1585
// path:
1586
//
1587
//        <local_delay_key> OP_CHECKSIG
1588
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1589
//
1590
// The keyspend path require knowledge of the top level revocation private key.
1591
func TaprootSecondLevelHtlcScript(revokeKey, delayKey *btcec.PublicKey,
1592
        csvDelay uint32, auxLeaf AuxTapLeaf,
NEW
1593
        opts ...TaprootScriptOpt) (*btcec.PublicKey, error) {
×
1594

×
1595
        // First, we'll make the tapscript tree that commits to the redemption
×
1596
        // path.
×
1597
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
×
NEW
1598
                delayKey, csvDelay, auxLeaf, opts...,
×
1599
        )
×
1600
        if err != nil {
×
1601
                return nil, err
×
1602
        }
×
1603

1604
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
×
1605

×
1606
        // With the tapscript root obtained, we'll tweak the revocation key
×
1607
        // with this value to obtain the key that the second level spend will
×
1608
        // create.
×
1609
        redemptionKey := txscript.ComputeTaprootOutputKey(
×
1610
                revokeKey, tapScriptRoot[:],
×
1611
        )
×
1612

×
1613
        return redemptionKey, nil
×
1614
}
1615

1616
// SecondLevelScriptTree is a tapscript tree used to spend the second level
1617
// HTLC output after the CSV delay has passed.
1618
type SecondLevelScriptTree struct {
1619
        ScriptTree
1620

1621
        // SuccessTapLeaf is the tapleaf for the redemption path.
1622
        SuccessTapLeaf txscript.TapLeaf
1623

1624
        // AuxLeaf is an optional leaf that can be used to extend the script
1625
        // tree.
1626
        AuxLeaf AuxTapLeaf
1627
}
1628

1629
// TaprootSecondLevelScriptTree constructs the tapscript tree used to spend the
1630
// second level HTLC output.
1631
func TaprootSecondLevelScriptTree(revokeKey, delayKey *btcec.PublicKey,
1632
        csvDelay uint32, auxLeaf AuxTapLeaf,
1633
        opts ...TaprootScriptOpt) (*SecondLevelScriptTree, error) {
253✔
1634

253✔
1635
        // First, we'll make the tapscript tree that commits to the redemption
253✔
1636
        // path.
253✔
1637
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
253✔
1638
                delayKey, csvDelay, auxLeaf, opts...,
253✔
1639
        )
253✔
1640
        if err != nil {
253✔
1641
                return nil, err
×
1642
        }
×
1643

1644
        // With the tree constructed, we can make the pkscript which is the
1645
        // taproot output key itself.
1646
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
253✔
1647
        outputKey := txscript.ComputeTaprootOutputKey(
253✔
1648
                revokeKey, tapScriptRoot[:],
253✔
1649
        )
253✔
1650

253✔
1651
        return &SecondLevelScriptTree{
253✔
1652
                ScriptTree: ScriptTree{
253✔
1653
                        TaprootKey:    outputKey,
253✔
1654
                        TapscriptTree: tapScriptTree,
253✔
1655
                        TapscriptRoot: tapScriptRoot[:],
253✔
1656
                        InternalKey:   revokeKey,
253✔
1657
                },
253✔
1658
                SuccessTapLeaf: tapScriptTree.LeafMerkleProofs[0].TapLeaf,
253✔
1659
                AuxLeaf:        auxLeaf,
253✔
1660
        }, nil
253✔
1661
}
1662

1663
// WitnessScriptToSign returns the witness script that we'll use when signing
1664
// for the remote party, and also verifying signatures on our transactions. As
1665
// an example, when we create an outgoing HTLC for the remote party, we want to
1666
// sign their success path.
1667
func (s *SecondLevelScriptTree) WitnessScriptToSign() []byte {
×
1668
        return s.SuccessTapLeaf.Script
×
1669
}
×
1670

1671
// WitnessScriptForPath returns the witness script for the given spending path.
1672
// An error is returned if the path is unknown.
1673
func (s *SecondLevelScriptTree) WitnessScriptForPath(
1674
        path ScriptPath) ([]byte, error) {
19✔
1675

19✔
1676
        switch path {
19✔
1677
        case ScriptPathDelay:
×
1678
                fallthrough
×
1679
        case ScriptPathSuccess:
19✔
1680
                return s.SuccessTapLeaf.Script, nil
19✔
1681

1682
        default:
×
1683
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1684
        }
1685
}
1686

1687
// CtrlBlockForPath returns the control block for the given spending path. For
1688
// script types that don't have a control block, nil is returned.
1689
func (s *SecondLevelScriptTree) CtrlBlockForPath(
1690
        path ScriptPath) (*txscript.ControlBlock, error) {
19✔
1691

19✔
1692
        switch path {
19✔
1693
        case ScriptPathDelay:
×
1694
                fallthrough
×
1695
        case ScriptPathSuccess:
19✔
1696
                return lnutils.Ptr(MakeTaprootCtrlBlock(
19✔
1697
                        s.SuccessTapLeaf.Script, s.InternalKey,
19✔
1698
                        s.TapscriptTree,
19✔
1699
                )), nil
19✔
1700

1701
        default:
×
1702
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1703
        }
1704
}
1705

1706
// Tree returns the underlying ScriptTree of the SecondLevelScriptTree.
1707
func (s *SecondLevelScriptTree) Tree() ScriptTree {
×
1708
        return s.ScriptTree
×
1709
}
×
1710

1711
// A compile time check to ensure SecondLevelScriptTree implements the
1712
// TapscriptDescriptor interface.
1713
var _ TapscriptDescriptor = (*SecondLevelScriptTree)(nil)
1714

1715
// TaprootHtlcSpendRevoke spends a second-level HTLC output via the revocation
1716
// path. This uses the top level keyspend path to redeem the contested output.
1717
//
1718
// The passed SignDescriptor MUST have the proper witness script and also the
1719
// proper top-level tweak derived from the tapscript tree for the second level
1720
// output.
1721
func TaprootHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1722
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
17✔
1723

17✔
1724
        // We don't need any spacial modifications to the transaction as this
17✔
1725
        // is just sweeping a revoked HTLC output. So we'll generate a regular
17✔
1726
        // schnorr signature.
17✔
1727
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
17✔
1728
        if err != nil {
17✔
1729
                return nil, err
×
1730
        }
×
1731

1732
        // The witness stack in this case is pretty simple: we only need to
1733
        // specify the signature generated.
1734
        witnessStack := make(wire.TxWitness, 1)
17✔
1735
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
17✔
1736

17✔
1737
        return witnessStack, nil
17✔
1738
}
1739

1740
// TaprootHtlcSpendSuccess spends a second-level HTLC output via the redemption
1741
// path. This should be used to sweep funds after the pre-image is known.
1742
//
1743
// NOTE: The caller MUST set the txn version, sequence number, and sign
1744
// descriptor's sig hash cache before invocation.
1745
func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
1746
        sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1747
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
29✔
1748

29✔
1749
        // First, we'll generate the sweep signature based on the populated
29✔
1750
        // sign desc. This should give us a valid schnorr signature for the
29✔
1751
        // sole script path leaf.
29✔
1752
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
29✔
1753
        if err != nil {
29✔
1754
                return nil, err
×
1755
        }
×
1756

1757
        var ctrlBlock []byte
29✔
1758
        if signDesc.ControlBlock == nil {
50✔
1759
                // Now that we have the sweep signature, we'll construct the
21✔
1760
                // control block needed to spend the script path.
21✔
1761
                redeemControlBlock := MakeTaprootCtrlBlock(
21✔
1762
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
21✔
1763
                )
21✔
1764

21✔
1765
                ctrlBlock, err = redeemControlBlock.ToBytes()
21✔
1766
                if err != nil {
21✔
1767
                        return nil, err
×
1768
                }
×
1769
        } else {
8✔
1770
                ctrlBlock = signDesc.ControlBlock
8✔
1771
        }
8✔
1772

1773
        // Now that we have the redeem control block, we can construct the
1774
        // final witness needed to spend the script:
1775
        //
1776
        //  <success sig> <success script> <control_block>
1777
        witnessStack := make(wire.TxWitness, 3)
29✔
1778
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
29✔
1779
        witnessStack[1] = signDesc.WitnessScript
29✔
1780
        witnessStack[2] = ctrlBlock
29✔
1781

29✔
1782
        return witnessStack, nil
29✔
1783
}
1784

1785
// LeaseSecondLevelHtlcScript is the uniform script that's used as the output
1786
// for the second-level HTLC transactions. The second level transaction acts as
1787
// a sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1788
// spent in a particular way, and to a particular output.
1789
//
1790
// Possible Input Scripts:
1791
//
1792
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1793
//     state:
1794
//     <revoke sig> 1
1795
//
1796
//   - To claim an HTLC output, either with a pre-image or due to a timeout:
1797
//     <delay sig> 0
1798
//
1799
// Output Script:
1800
//
1801
//         OP_IF
1802
//                <revoke key>
1803
//         OP_ELSE
1804
//                <lease maturity in blocks>
1805
//                OP_CHECKLOCKTIMEVERIFY
1806
//                OP_DROP
1807
//                <delay in blocks>
1808
//                OP_CHECKSEQUENCEVERIFY
1809
//                OP_DROP
1810
//                <delay key>
1811
//         OP_ENDIF
1812
//         OP_CHECKSIG.
1813
func LeaseSecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1814
        csvDelay, cltvExpiry uint32) ([]byte, error) {
7✔
1815

7✔
1816
        // Build a script template with conditional paths for revocation and
7✔
1817
        // normal spending If this is the revocation clause, the spender will
7✔
1818
        // push a 1, forcing the first path Otherwise, this is either the sender
7✔
1819
        // or receiver of the HTLC attempting to claim
7✔
1820
        return txscript.ScriptTemplate(
7✔
1821
                `
7✔
1822
                OP_IF
7✔
1823
                        {{ hex .RevokeKey }}
7✔
1824
                OP_ELSE
7✔
1825
                        {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
7✔
1826
                        {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP
7✔
1827
                        {{ hex .DelayKey }}
7✔
1828
                OP_ENDIF OP_CHECKSIG`,
7✔
1829
                txscript.WithScriptTemplateParams(TemplateParams{
7✔
1830
                        "RevokeKey":  revocationKey.SerializeCompressed(),
7✔
1831
                        "CltvExpiry": int64(cltvExpiry),
7✔
1832
                        "CsvDelay":   int64(csvDelay),
7✔
1833
                        "DelayKey":   delayKey.SerializeCompressed(),
7✔
1834
                }),
7✔
1835
        )
7✔
1836
}
7✔
1837

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

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

11✔
1849
        // Finally, OP_CSV requires that the version of the transaction
11✔
1850
        // spending a pkscript with OP_CSV within it *must* be >= 2.
11✔
1851
        sweepTx.Version = 2
11✔
1852

11✔
1853
        // As we mutated the transaction, we'll re-calculate the sighashes for
11✔
1854
        // this instance.
11✔
1855
        signDesc.SigHashes = NewTxSigHashesV0Only(sweepTx)
11✔
1856

11✔
1857
        // With the proper sequence and version set, we'll now sign the timeout
11✔
1858
        // transaction using the passed signed descriptor. In order to generate
11✔
1859
        // a valid signature, then signDesc should be using the base delay
11✔
1860
        // public key, and the proper single tweak bytes.
11✔
1861
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
11✔
1862
        if err != nil {
11✔
1863
                return nil, err
×
1864
        }
×
1865

1866
        // We set a zero as the first element the witness stack (ignoring the
1867
        // witness script), in order to force execution to the second portion
1868
        // of the if clause.
1869
        witnessStack := wire.TxWitness(make([][]byte, 3))
11✔
1870
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
11✔
1871
        witnessStack[1] = nil
11✔
1872
        witnessStack[2] = signDesc.WitnessScript
11✔
1873

11✔
1874
        return witnessStack, nil
11✔
1875
}
1876

1877
// HtlcSpendRevoke spends a second-level HTLC output. This function is to be
1878
// used by the sender or receiver of an HTLC to claim the HTLC after a revoked
1879
// commitment transaction was broadcast.
1880
func HtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1881
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
14✔
1882

14✔
1883
        // We don't need any spacial modifications to the transaction as this
14✔
1884
        // is just sweeping a revoked HTLC output. So we'll generate a regular
14✔
1885
        // witness signature.
14✔
1886
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
14✔
1887
        if err != nil {
14✔
1888
                return nil, err
×
1889
        }
×
1890

1891
        // We set a one as the first element the witness stack (ignoring the
1892
        // witness script), in order to force execution to the revocation
1893
        // clause in the second level HTLC script.
1894
        witnessStack := wire.TxWitness(make([][]byte, 3))
14✔
1895
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
14✔
1896
        witnessStack[1] = []byte{1}
14✔
1897
        witnessStack[2] = signDesc.WitnessScript
14✔
1898

14✔
1899
        return witnessStack, nil
14✔
1900
}
1901

1902
// HtlcSecondLevelSpend exposes the public witness generation function for
1903
// spending an HTLC success transaction, either due to an expiring time lock or
1904
// having had the payment preimage. This method is able to spend any
1905
// second-level HTLC transaction, assuming the caller sets the locktime or
1906
// seqno properly.
1907
//
1908
// NOTE: The caller MUST set the txn version, sequence number, and sign
1909
// descriptor's sig hash cache before invocation.
1910
func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor,
1911
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
1912

4✔
1913
        // With the proper sequence and version set, we'll now sign the timeout
4✔
1914
        // transaction using the passed signed descriptor. In order to generate
4✔
1915
        // a valid signature, then signDesc should be using the base delay
4✔
1916
        // public key, and the proper single tweak bytes.
4✔
1917
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
4✔
1918
        if err != nil {
4✔
1919
                return nil, err
×
1920
        }
×
1921

1922
        // We set a zero as the first element the witness stack (ignoring the
1923
        // witness script), in order to force execution to the second portion
1924
        // of the if clause.
1925
        witnessStack := wire.TxWitness(make([][]byte, 3))
4✔
1926
        witnessStack[0] = append(sweepSig.Serialize(), byte(txscript.SigHashAll))
4✔
1927
        witnessStack[1] = nil
4✔
1928
        witnessStack[2] = signDesc.WitnessScript
4✔
1929

4✔
1930
        return witnessStack, nil
4✔
1931
}
1932

1933
// LockTimeToSequence converts the passed relative locktime to a sequence
1934
// number in accordance to BIP-68.
1935
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
1936
//   - (Compatibility)
1937
func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
28✔
1938
        if !isSeconds {
56✔
1939
                // The locktime is to be expressed in confirmations.
28✔
1940
                return locktime
28✔
1941
        }
28✔
1942

1943
        // Set the 22nd bit which indicates the lock time is in seconds, then
1944
        // shift the locktime over by 9 since the time granularity is in
1945
        // 512-second intervals (2^9). This results in a max lock-time of
1946
        // 33,554,431 seconds, or 1.06 years.
1947
        return SequenceLockTimeSeconds | (locktime >> 9)
×
1948
}
1949

1950
// CommitScriptToSelf constructs the public key script for the output on the
1951
// commitment transaction paying to the "owner" of said commitment transaction.
1952
// If the other party obtains the revocation private key for this commitment,
1953
// then they can claim all the settled funds in the channel, plus the unsettled
1954
// funds.
1955
//
1956
// Possible Input Scripts:
1957
//
1958
//        REVOKE:     <sig> 1
1959
//        SENDRSWEEP: <sig> <emptyvector>
1960
//
1961
// Output Script:
1962
//
1963
//        OP_IF
1964
//            <revokeKey>
1965
//        OP_ELSE
1966
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
1967
//            <selfKey>
1968
//        OP_ENDIF
1969
//        OP_CHECKSIG
1970
func CommitScriptToSelf(csvTimeout uint32, selfKey, revokeKey *btcec.PublicKey) ([]byte, error) {
9,948✔
1971
        // This script is spendable under two conditions: either the
9,948✔
1972
        // 'csvTimeout' has passed and we can redeem our funds, or they can
9,948✔
1973
        // produce a valid signature with the revocation public key. The
9,948✔
1974
        // revocation public key will *only* be known to the other party if we
9,948✔
1975
        // have divulged the revocation hash, allowing them to homomorphically
9,948✔
1976
        // derive the proper private key which corresponds to the revoke public
9,948✔
1977
        // key.
9,948✔
1978
        return txscript.ScriptTemplate(
9,948✔
1979
                `
9,948✔
1980
                OP_IF
9,948✔
1981
                        {{ hex .RevokeKey }}
9,948✔
1982
                OP_ELSE
9,948✔
1983
                        {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP
9,948✔
1984
                        {{ hex .SelfKey }}
9,948✔
1985
                OP_ENDIF
9,948✔
1986
                OP_CHECKSIG`,
9,948✔
1987
                txscript.WithScriptTemplateParams(TemplateParams{
9,948✔
1988
                        "RevokeKey":  revokeKey.SerializeCompressed(),
9,948✔
1989
                        "CsvTimeout": int64(csvTimeout),
9,948✔
1990
                        "SelfKey":    selfKey.SerializeCompressed(),
9,948✔
1991
                }),
9,948✔
1992
        )
9,948✔
1993
}
9,948✔
1994

1995
// CommitScriptTree holds the taproot output key (in this case the revocation
1996
// key, or a NUMs point for the remote output) along with the tapscript leaf
1997
// that can spend the output after a delay.
1998
type CommitScriptTree struct {
1999
        ScriptTree
2000

2001
        // SettleLeaf is the leaf used to settle the output after the delay.
2002
        SettleLeaf txscript.TapLeaf
2003

2004
        // RevocationLeaf is the leaf used to spend the output with the
2005
        // revocation key signature.
2006
        RevocationLeaf txscript.TapLeaf
2007

2008
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
2009
        // commitment script tree with new spend paths, or just as extra
2010
        // commitment space. When present, this leaf will always be in the
2011
        // left-most or right-most area of the tapscript tree.
2012
        AuxLeaf AuxTapLeaf
2013
}
2014

2015
// A compile time check to ensure CommitScriptTree implements the
2016
// TapscriptDescriptor interface.
2017
var _ TapscriptDescriptor = (*CommitScriptTree)(nil)
2018

2019
// WitnessScriptToSign returns the witness script that we'll use when signing
2020
// for the remote party, and also verifying signatures on our transactions. As
2021
// an example, when we create an outgoing HTLC for the remote party, we want to
2022
// sign their success path.
2023
func (c *CommitScriptTree) WitnessScriptToSign() []byte {
×
2024
        // TODO(roasbeef): abstraction leak here? always dependent
×
2025
        return nil
×
2026
}
×
2027

2028
// WitnessScriptForPath returns the witness script for the given spending path.
2029
// An error is returned if the path is unknown.
2030
func (c *CommitScriptTree) WitnessScriptForPath(
2031
        path ScriptPath) ([]byte, error) {
11✔
2032

11✔
2033
        switch path {
11✔
2034
        // For the commitment output, the delay and success path are the same,
2035
        // so we'll fall through here to success.
2036
        case ScriptPathDelay:
11✔
2037
                fallthrough
11✔
2038
        case ScriptPathSuccess:
11✔
2039
                return c.SettleLeaf.Script, nil
11✔
2040
        case ScriptPathRevocation:
4✔
2041
                return c.RevocationLeaf.Script, nil
4✔
2042
        default:
×
2043
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2044
        }
2045
}
2046

2047
// CtrlBlockForPath returns the control block for the given spending path. For
2048
// script types that don't have a control block, nil is returned.
2049
func (c *CommitScriptTree) CtrlBlockForPath(
2050
        path ScriptPath) (*txscript.ControlBlock, error) {
11✔
2051

11✔
2052
        switch path {
11✔
2053
        case ScriptPathDelay:
11✔
2054
                fallthrough
11✔
2055
        case ScriptPathSuccess:
11✔
2056
                return lnutils.Ptr(MakeTaprootCtrlBlock(
11✔
2057
                        c.SettleLeaf.Script, c.InternalKey,
11✔
2058
                        c.TapscriptTree,
11✔
2059
                )), nil
11✔
2060
        case ScriptPathRevocation:
4✔
2061
                return lnutils.Ptr(MakeTaprootCtrlBlock(
4✔
2062
                        c.RevocationLeaf.Script, c.InternalKey,
4✔
2063
                        c.TapscriptTree,
4✔
2064
                )), nil
4✔
2065
        default:
×
2066
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2067
        }
2068
}
2069

2070
// Tree returns the underlying ScriptTree of the CommitScriptTree.
2071
func (c *CommitScriptTree) Tree() ScriptTree {
×
2072
        return c.ScriptTree
×
2073
}
×
2074

2075
// taprootScriptOpts is a set of options that modify the behavior of the way we
2076
// create taproot scripts.
2077
type taprootScriptOpts struct {
2078
        prodScript bool
2079
}
2080

2081
// TaprootScriptOpt is a functional option that allows us to modify the behavior
2082
// of the taproot script creation.
2083
type TaprootScriptOpt func(*taprootScriptOpts)
2084

2085
// defaultTaprootScriptOpt is the default set of options that we use when
2086
// creating taproot scripts.
2087
func defaultTaprootScriptOpt() *taprootScriptOpts {
3,583✔
2088
        return &taprootScriptOpts{
3,583✔
2089
                prodScript: false,
3,583✔
2090
        }
3,583✔
2091
}
3,583✔
2092

2093
// WithProdScripts is a functional option that allows us to create scripts to
2094
// match the final version of the taproot channels.
2095
func WithProdScripts() func(*taprootScriptOpts) {
133✔
2096
        return func(o *taprootScriptOpts) {
266✔
2097
                o.prodScript = true
133✔
2098
        }
133✔
2099
}
2100

2101
// NewLocalCommitScriptTree returns a new CommitScript tree that can be used to
2102
// create and spend the commitment output for the local party.
2103
func NewLocalCommitScriptTree(csvTimeout uint32, selfKey,
2104
        revokeKey *btcec.PublicKey, auxLeaf AuxTapLeaf,
2105
        opts ...TaprootScriptOpt) (*CommitScriptTree, error) {
1,853✔
2106

1,853✔
2107
        // First, we'll need to construct the tapLeaf that'll be our delay CSV
1,853✔
2108
        // clause.
1,853✔
2109
        delayScript, err := TaprootLocalCommitDelayScript(
1,853✔
2110
                csvTimeout, selfKey, opts...,
1,853✔
2111
        )
1,853✔
2112
        if err != nil {
1,853✔
2113
                return nil, err
×
2114
        }
×
2115

2116
        // Next, we'll need to construct the revocation path, which is just a
2117
        // simple checksig script.
2118
        revokeScript, err := TaprootLocalCommitRevokeScript(
1,853✔
2119
                selfKey, revokeKey, opts...,
1,853✔
2120
        )
1,853✔
2121
        if err != nil {
1,853✔
2122
                return nil, err
×
2123
        }
×
2124

2125
        // With both scripts computed, we'll now create a tapscript tree with
2126
        // the two leaves, and then obtain a root from that.
2127
        delayTapLeaf := txscript.NewBaseTapLeaf(delayScript)
1,853✔
2128
        revokeTapLeaf := txscript.NewBaseTapLeaf(revokeScript)
1,853✔
2129

1,853✔
2130
        tapLeaves := []txscript.TapLeaf{delayTapLeaf, revokeTapLeaf}
1,853✔
2131
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
1,855✔
2132
                tapLeaves = append(tapLeaves, l)
2✔
2133
        })
2✔
2134

2135
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
1,853✔
2136
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
1,853✔
2137

1,853✔
2138
        // Now that we have our root, we can arrive at the final output script
1,853✔
2139
        // by tweaking the internal key with this root.
1,853✔
2140
        toLocalOutputKey := txscript.ComputeTaprootOutputKey(
1,853✔
2141
                &TaprootNUMSKey, tapScriptRoot[:],
1,853✔
2142
        )
1,853✔
2143

1,853✔
2144
        return &CommitScriptTree{
1,853✔
2145
                ScriptTree: ScriptTree{
1,853✔
2146
                        TaprootKey:    toLocalOutputKey,
1,853✔
2147
                        TapscriptTree: tapScriptTree,
1,853✔
2148
                        TapscriptRoot: tapScriptRoot[:],
1,853✔
2149
                        InternalKey:   &TaprootNUMSKey,
1,853✔
2150
                },
1,853✔
2151
                SettleLeaf:     delayTapLeaf,
1,853✔
2152
                RevocationLeaf: revokeTapLeaf,
1,853✔
2153
                AuxLeaf:        auxLeaf,
1,853✔
2154
        }, nil
1,853✔
2155
}
2156

2157
// TaprootLocalCommitDelayScript builds the tap leaf with the CSV delay script
2158
// for the to-local output.
2159
func TaprootLocalCommitDelayScript(csvTimeout uint32,
2160
        selfKey *btcec.PublicKey, opts ...TaprootScriptOpt) ([]byte, error) {
1,854✔
2161

1,854✔
2162
        opt := defaultTaprootScriptOpt()
1,854✔
2163
        for _, o := range opts {
1,886✔
2164
                o(opt)
32✔
2165
        }
32✔
2166

2167
        var scriptTemplate string
1,854✔
2168
        switch {
1,854✔
2169
        case opt.prodScript:
32✔
2170
                scriptTemplate = `
32✔
2171
                {{ hex .SelfKey }} OP_CHECKSIGVERIFY
32✔
2172
                {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY`
32✔
2173
        default:
1,826✔
2174
                scriptTemplate = `
1,826✔
2175
                {{ hex .SelfKey }} OP_CHECKSIG
1,826✔
2176
                {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP`
1,826✔
2177
        }
2178

2179
        return txscript.ScriptTemplate(
1,854✔
2180
                scriptTemplate,
1,854✔
2181
                txscript.WithScriptTemplateParams(TemplateParams{
1,854✔
2182
                        "SelfKey":    schnorr.SerializePubKey(selfKey),
1,854✔
2183
                        "CsvTimeout": int64(csvTimeout),
1,854✔
2184
                }),
1,854✔
2185
        )
1,854✔
2186
}
2187

2188
// TaprootLocalCommitRevokeScript builds the tap leaf with the revocation path
2189
// for the to-local output.
2190
func TaprootLocalCommitRevokeScript(selfKey, revokeKey *btcec.PublicKey,
2191
        _ ...TaprootScriptOpt) ([]byte, error) {
1,856✔
2192

1,856✔
2193
        return txscript.ScriptTemplate(
1,856✔
2194
                `
1,856✔
2195
                {{ hex .SelfKey }} OP_DROP 
1,856✔
2196
                {{ hex .RevokeKey }} OP_CHECKSIG`,
1,856✔
2197
                txscript.WithScriptTemplateParams(TemplateParams{
1,856✔
2198
                        "SelfKey":   schnorr.SerializePubKey(selfKey),
1,856✔
2199
                        "RevokeKey": schnorr.SerializePubKey(revokeKey),
1,856✔
2200
                }),
1,856✔
2201
        )
1,856✔
2202
}
1,856✔
2203

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

×
2240
        commitScriptTree, err := NewLocalCommitScriptTree(
×
2241
                csvTimeout, selfKey, revokeKey, NoneTapLeaf(),
×
2242
        )
×
2243
        if err != nil {
×
2244
                return nil, err
×
2245
        }
×
2246

2247
        return commitScriptTree.TaprootKey, nil
×
2248
}
2249

2250
// MakeTaprootCtrlBlock takes a leaf script, the internal key (usually the
2251
// revoke key), and a script tree and creates a valid control block for a spend
2252
// of the leaf.
2253
func MakeTaprootCtrlBlock(leafScript []byte, internalKey *btcec.PublicKey,
2254
        scriptTree *txscript.IndexedTapScriptTree) txscript.ControlBlock {
221✔
2255

221✔
2256
        tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
221✔
2257
        scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
221✔
2258
        settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
221✔
2259

221✔
2260
        return settleMerkleProof.ToControlBlock(internalKey)
221✔
2261
}
221✔
2262

2263
// TaprootCommitSpendSuccess constructs a valid witness allowing a node to
2264
// sweep the settled taproot output after the delay has passed for a force
2265
// close.
2266
func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
2267
        sweepTx *wire.MsgTx,
2268
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
25✔
2269

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

2286
                ctrlBlockBytes = ctrlBytes
21✔
2287
        } else {
4✔
2288
                ctrlBlockBytes = signDesc.ControlBlock
4✔
2289
        }
4✔
2290

2291
        // With the control block created, we'll now generate the signature we
2292
        // need to authorize the spend.
2293
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
25✔
2294
        if err != nil {
25✔
2295
                return nil, err
×
2296
        }
×
2297

2298
        // The final witness stack will be:
2299
        //
2300
        //  <sweep sig> <sweep script> <control block>
2301
        witnessStack := make(wire.TxWitness, 3)
25✔
2302
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
25✔
2303
        witnessStack[1] = signDesc.WitnessScript
25✔
2304
        witnessStack[2] = ctrlBlockBytes
25✔
2305

25✔
2306
        return witnessStack, nil
25✔
2307
}
2308

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

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

2327
                ctrlBlockBytes = revokeBytes
17✔
2328
        } else {
689✔
2329
                ctrlBlockBytes = signDesc.ControlBlock
689✔
2330
        }
689✔
2331

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

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

706✔
2347
        return witnessStack, nil
706✔
2348
}
2349

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

7✔
2374
        // This script is spendable under two conditions: either the
7✔
2375
        // 'csvTimeout' has passed and we can redeem our funds, or they can
7✔
2376
        // produce a valid signature with the revocation public key. The
7✔
2377
        // revocation public key will *only* be known to the other party if we
7✔
2378
        // have divulged the revocation hash, allowing them to homomorphically
7✔
2379
        // derive the proper private key which corresponds to the revoke public
7✔
2380
        // key.
7✔
2381
        return txscript.ScriptTemplate(
7✔
2382
                `
7✔
2383
                OP_IF
7✔
2384
                        {{ hex .RevokeKey }}
7✔
2385
                OP_ELSE
7✔
2386
                        {{ .LeaseExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
7✔
2387
                        {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP
7✔
2388
                        {{ hex .SelfKey }}
7✔
2389
                OP_ENDIF
7✔
2390
                OP_CHECKSIG`,
7✔
2391
                txscript.WithScriptTemplateParams(TemplateParams{
7✔
2392
                        "RevokeKey":   revokeKey.SerializeCompressed(),
7✔
2393
                        "LeaseExpiry": int64(leaseExpiry),
7✔
2394
                        "CsvTimeout":  int64(csvTimeout),
7✔
2395
                        "SelfKey":     selfKey.SerializeCompressed(),
7✔
2396
                }),
7✔
2397
        )
7✔
2398
}
7✔
2399

2400
// CommitSpendTimeout constructs a valid witness allowing the owner of a
2401
// particular commitment transaction to spend the output returning settled
2402
// funds back to themselves after a relative block timeout.  In order to
2403
// properly spend the transaction, the target input's sequence number should be
2404
// set accordingly based off of the target relative block timeout within the
2405
// redeem script.  Additionally, OP_CSV requires that the version of the
2406
// transaction spending a pkscript with OP_CSV within it *must* be >= 2.
2407
func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
2408
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
10✔
2409

10✔
2410
        // Ensure the transaction version supports the validation of sequence
10✔
2411
        // locks and CSV semantics.
10✔
2412
        if sweepTx.Version < 2 {
10✔
2413
                return nil, fmt.Errorf("version of passed transaction MUST "+
×
2414
                        "be >= 2, not %v", sweepTx.Version)
×
2415
        }
×
2416

2417
        // With the sequence number in place, we're now able to properly sign
2418
        // off on the sweep transaction.
2419
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
10✔
2420
        if err != nil {
10✔
2421
                return nil, err
×
2422
        }
×
2423

2424
        // Place an empty byte as the first item in the evaluated witness stack
2425
        // to force script execution to the timeout spend clause. We need to
2426
        // place an empty byte in order to ensure our script is still valid
2427
        // from the PoV of nodes that are enforcing minimal OP_IF/OP_NOTIF.
2428
        witnessStack := wire.TxWitness(make([][]byte, 3))
10✔
2429
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
10✔
2430
        witnessStack[1] = nil
10✔
2431
        witnessStack[2] = signDesc.WitnessScript
10✔
2432

10✔
2433
        return witnessStack, nil
10✔
2434
}
2435

2436
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
2437
// settled output of a malicious counterparty who broadcasts a revoked
2438
// commitment transaction.
2439
//
2440
// NOTE: The passed SignDescriptor should include the raw (untweaked)
2441
// revocation base public key of the receiver and also the proper double tweak
2442
// value based on the commitment secret of the revoked commitment.
2443
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2444
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
41✔
2445

41✔
2446
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
41✔
2447
        if err != nil {
41✔
2448
                return nil, err
×
2449
        }
×
2450

2451
        // Place a 1 as the first item in the evaluated witness stack to
2452
        // force script execution to the revocation clause.
2453
        witnessStack := wire.TxWitness(make([][]byte, 3))
41✔
2454
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
41✔
2455
        witnessStack[1] = []byte{1}
41✔
2456
        witnessStack[2] = signDesc.WitnessScript
41✔
2457

41✔
2458
        return witnessStack, nil
41✔
2459
}
2460

2461
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
2462
// settled no-delay output on the counterparty's commitment transaction. If the
2463
// tweakless field is true, then we'll omit the set where we tweak the pubkey
2464
// with a random set of bytes, and use it directly in the witness stack.
2465
//
2466
// NOTE: The passed SignDescriptor should include the raw (untweaked) public
2467
// key of the receiver and also the proper single tweak value based on the
2468
// current commitment point.
2469
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
2470
        sweepTx *wire.MsgTx, tweakless bool) (wire.TxWitness, error) {
37✔
2471

37✔
2472
        if signDesc.KeyDesc.PubKey == nil {
37✔
2473
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2474
                        "KeyDesc pubkey")
×
2475
        }
×
2476

2477
        // This is just a regular p2wkh spend which looks something like:
2478
        //  * witness: <sig> <pubkey>
2479
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
37✔
2480
        if err != nil {
37✔
2481
                return nil, err
×
2482
        }
×
2483

2484
        // Finally, we'll manually craft the witness. The witness here is the
2485
        // exact same as a regular p2wkh witness, depending on the value of the
2486
        // tweakless bool.
2487
        witness := make([][]byte, 2)
37✔
2488
        witness[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
37✔
2489

37✔
2490
        switch tweakless {
37✔
2491
        // If we're tweaking the key, then we use the tweaked public key as the
2492
        // last item in the witness stack which was originally used to created
2493
        // the pkScript we're spending.
2494
        case false:
12✔
2495
                witness[1] = TweakPubKeyWithTweak(
12✔
2496
                        signDesc.KeyDesc.PubKey, signDesc.SingleTweak,
12✔
2497
                ).SerializeCompressed()
12✔
2498

2499
        // Otherwise, we can just use the raw pubkey, since there's no random
2500
        // value to be combined.
2501
        case true:
29✔
2502
                witness[1] = signDesc.KeyDesc.PubKey.SerializeCompressed()
29✔
2503
        }
2504

2505
        return witness, nil
37✔
2506
}
2507

2508
// CommitScriptUnencumbered constructs the public key script on the commitment
2509
// transaction paying to the "other" party. The constructed output is a normal
2510
// p2wkh output spendable immediately, requiring no contestation period.
2511
func CommitScriptUnencumbered(key *btcec.PublicKey) ([]byte, error) {
9,621✔
2512
        // This script goes to the "other" party, and is spendable immediately.
9,621✔
2513
        return txscript.ScriptTemplate(
9,621✔
2514
                `OP_0 {{ hex .PKHash }}`,
9,621✔
2515
                txscript.WithScriptTemplateParams(TemplateParams{
9,621✔
2516
                        "PKHash": btcutil.Hash160(key.SerializeCompressed()),
9,621✔
2517
                }),
9,621✔
2518
        )
9,621✔
2519
}
9,621✔
2520

2521
// CommitScriptToRemoteConfirmed constructs the script for the output on the
2522
// commitment transaction paying to the remote party of said commitment
2523
// transaction. The money can only be spend after one confirmation.
2524
//
2525
// Possible Input Scripts:
2526
//
2527
//        SWEEP: <sig>
2528
//
2529
// Output Script:
2530
//
2531
//        <key> OP_CHECKSIGVERIFY
2532
//        1 OP_CHECKSEQUENCEVERIFY
2533
func CommitScriptToRemoteConfirmed(key *btcec.PublicKey) ([]byte, error) {
294✔
2534
        // Only the given key can spend the output after one confirmation.
294✔
2535
        return txscript.ScriptTemplate(
294✔
2536
                `
294✔
2537
                {{ hex .Key }} OP_CHECKSIGVERIFY 
294✔
2538
                OP_1 OP_CHECKSEQUENCEVERIFY`,
294✔
2539
                txscript.WithScriptTemplateParams(TemplateParams{
294✔
2540
                        "Key": key.SerializeCompressed(),
294✔
2541
                }),
294✔
2542
        )
294✔
2543
}
294✔
2544

2545
// NewRemoteCommitScriptTree constructs a new script tree for the remote party
2546
// to sweep their funds after a hard coded 1 block delay.
2547
func NewRemoteCommitScriptTree(remoteKey *btcec.PublicKey,
2548
        auxLeaf AuxTapLeaf,
2549
        opts ...TaprootScriptOpt) (*CommitScriptTree, error) {
1,149✔
2550

1,149✔
2551
        opt := defaultTaprootScriptOpt()
1,149✔
2552
        for _, o := range opts {
1,177✔
2553
                o(opt)
28✔
2554
        }
28✔
2555

2556
        // First, construct the remote party's tapscript they'll use to sweep
2557
        // their outputs.
2558
        var scriptTemplate string
1,149✔
2559
        switch {
1,149✔
2560
        case opt.prodScript:
28✔
2561
                scriptTemplate = `
28✔
2562
                {{ hex .RemoteKey }} OP_CHECKSIGVERIFY
28✔
2563
                OP_1 OP_CHECKSEQUENCEVERIFY`
28✔
2564
        default:
1,125✔
2565
                scriptTemplate = `
1,125✔
2566
                {{ hex .RemoteKey }} OP_CHECKSIG
1,125✔
2567
                OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
1,125✔
2568
        }
2569

2570
        remoteScript, err := txscript.ScriptTemplate(
1,149✔
2571
                scriptTemplate,
1,149✔
2572
                txscript.WithScriptTemplateParams(TemplateParams{
1,149✔
2573
                        "RemoteKey": schnorr.SerializePubKey(remoteKey),
1,149✔
2574
                }),
1,149✔
2575
        )
1,149✔
2576
        if err != nil {
1,149✔
2577
                return nil, err
×
2578
        }
×
2579

2580
        tapLeaf := txscript.NewBaseTapLeaf(remoteScript)
1,149✔
2581

1,149✔
2582
        tapLeaves := []txscript.TapLeaf{tapLeaf}
1,149✔
2583
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
1,151✔
2584
                tapLeaves = append(tapLeaves, l)
2✔
2585
        })
2✔
2586

2587
        // With this script constructed, we'll map that into a tapLeaf, then
2588
        // make a new tapscript root from that.
2589
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
1,149✔
2590
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
1,149✔
2591

1,149✔
2592
        // Now that we have our root, we can arrive at the final output script
1,149✔
2593
        // by tweaking the internal key with this root.
1,149✔
2594
        toRemoteOutputKey := txscript.ComputeTaprootOutputKey(
1,149✔
2595
                &TaprootNUMSKey, tapScriptRoot[:],
1,149✔
2596
        )
1,149✔
2597

1,149✔
2598
        return &CommitScriptTree{
1,149✔
2599
                ScriptTree: ScriptTree{
1,149✔
2600
                        TaprootKey:    toRemoteOutputKey,
1,149✔
2601
                        TapscriptTree: tapScriptTree,
1,149✔
2602
                        TapscriptRoot: tapScriptRoot[:],
1,149✔
2603
                        InternalKey:   &TaprootNUMSKey,
1,149✔
2604
                },
1,149✔
2605
                SettleLeaf: tapLeaf,
1,149✔
2606
                AuxLeaf:    auxLeaf,
1,149✔
2607
        }, nil
1,149✔
2608
}
2609

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

×
2625
        commitScriptTree, err := NewRemoteCommitScriptTree(remoteKey, auxLeaf)
×
2626
        if err != nil {
×
2627
                return nil, err
×
2628
        }
×
2629

2630
        return commitScriptTree.TaprootKey, nil
×
2631
}
2632

2633
// TaprootCommitRemoteSpend allows the remote party to sweep their output into
2634
// their wallet after an enforced 1 block delay.
2635
func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
2636
        sweepTx *wire.MsgTx,
2637
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
713✔
2638

713✔
2639
        // First, we'll need to construct a valid control block to execute the
713✔
2640
        // leaf script for sweep settlement.
713✔
2641
        var ctrlBlockBytes []byte
713✔
2642
        if signDesc.ControlBlock == nil {
738✔
2643
                settleControlBlock := MakeTaprootCtrlBlock(
25✔
2644
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
25✔
2645
                )
25✔
2646
                ctrlBytes, err := settleControlBlock.ToBytes()
25✔
2647
                if err != nil {
25✔
2648
                        return nil, err
×
2649
                }
×
2650

2651
                ctrlBlockBytes = ctrlBytes
25✔
2652
        } else {
688✔
2653
                ctrlBlockBytes = signDesc.ControlBlock
688✔
2654
        }
688✔
2655

2656
        // With the control block created, we'll now generate the signature we
2657
        // need to authorize the spend.
2658
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
713✔
2659
        if err != nil {
713✔
2660
                return nil, err
×
2661
        }
×
2662

2663
        // The final witness stack will be:
2664
        //
2665
        //  <sweep sig> <sweep script> <control block>
2666
        witnessStack := make(wire.TxWitness, 3)
713✔
2667
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
713✔
2668
        witnessStack[1] = signDesc.WitnessScript
713✔
2669
        witnessStack[2] = ctrlBlockBytes
713✔
2670

713✔
2671
        return witnessStack, nil
713✔
2672
}
2673

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

7✔
2690
        // This script adds lease expiration constraint in addition to the
7✔
2691
        // standard remote confirmed script requirements.
7✔
2692
        return txscript.ScriptTemplate(
7✔
2693
                `
7✔
2694
                {{ hex .Key }} OP_CHECKSIGVERIFY
7✔
2695
                {{ .LeaseExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
7✔
2696
                OP_1 OP_CHECKSEQUENCEVERIFY`,
7✔
2697
                txscript.WithScriptTemplateParams(TemplateParams{
7✔
2698
                        "Key":         key.SerializeCompressed(),
7✔
2699
                        "LeaseExpiry": int64(leaseExpiry),
7✔
2700
                }),
7✔
2701
        )
7✔
2702
}
7✔
2703

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

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

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

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

16✔
2728
        return witnessStack, nil
16✔
2729
}
2730

2731
// CommitScriptAnchor constructs the script for the anchor output spendable by
2732
// the given key immediately, or by anyone after 16 confirmations.
2733
//
2734
// Possible Input Scripts:
2735
//
2736
//        By owner:                                <sig>
2737
//        By anyone (after 16 conf):        <emptyvector>
2738
//
2739
// Output Script:
2740
//
2741
//        <funding_pubkey> OP_CHECKSIG OP_IFDUP
2742
//        OP_NOTIF
2743
//          OP_16 OP_CSV
2744
//        OP_ENDIF
2745
func CommitScriptAnchor(key *btcec.PublicKey) ([]byte, error) {
515✔
2746
        // Build the anchor script with two possible spending paths:
515✔
2747
        // 1. Spend immediately with key (the normal path)
515✔
2748
        // 2. Spend after 16 confirmations by anyone (the alternative path)
515✔
2749
        return txscript.ScriptTemplate(
515✔
2750
                `
515✔
2751
                {{ hex .Key }} OP_CHECKSIG
515✔
2752
                OP_IFDUP
515✔
2753
                OP_NOTIF
515✔
2754
                        OP_16 OP_CHECKSEQUENCEVERIFY
515✔
2755
                OP_ENDIF`,
515✔
2756
                txscript.WithScriptTemplateParams(TemplateParams{
515✔
2757
                        "Key": key.SerializeCompressed(),
515✔
2758
                }),
515✔
2759
        )
515✔
2760
}
515✔
2761

2762
// AnchorScriptTree holds all the contents needed to sweep a taproot anchor
2763
// output on chain.
2764
type AnchorScriptTree struct {
2765
        ScriptTree
2766

2767
        // SweepLeaf is the leaf used to settle the output after the delay.
2768
        SweepLeaf txscript.TapLeaf
2769
}
2770

2771
// NewAnchorScriptTree makes a new script tree for an anchor output with the
2772
// passed anchor key.
2773
func NewAnchorScriptTree(
2774
        anchorKey *btcec.PublicKey) (*AnchorScriptTree, error) {
794✔
2775

794✔
2776
        // The main script used is just a OP_16 CSV (anyone can sweep after 16
794✔
2777
        // blocks).
794✔
2778
        anchorScript, err := txscript.ScriptTemplate(
794✔
2779
                `OP_16 OP_CHECKSEQUENCEVERIFY`,
794✔
2780
        )
794✔
2781
        if err != nil {
794✔
2782
                return nil, err
×
2783
        }
×
2784

2785
        // With the script, we can make our sole leaf, then derive the root
2786
        // from that.
2787
        tapLeaf := txscript.NewBaseTapLeaf(anchorScript)
794✔
2788
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)
794✔
2789
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
794✔
2790

794✔
2791
        // Now that we have our root, we can arrive at the final output script
794✔
2792
        // by tweaking the internal key with this root.
794✔
2793
        anchorOutputKey := txscript.ComputeTaprootOutputKey(
794✔
2794
                anchorKey, tapScriptRoot[:],
794✔
2795
        )
794✔
2796

794✔
2797
        return &AnchorScriptTree{
794✔
2798
                ScriptTree: ScriptTree{
794✔
2799
                        TaprootKey:    anchorOutputKey,
794✔
2800
                        TapscriptTree: tapScriptTree,
794✔
2801
                        TapscriptRoot: tapScriptRoot[:],
794✔
2802
                        InternalKey:   anchorKey,
794✔
2803
                },
794✔
2804
                SweepLeaf: tapLeaf,
794✔
2805
        }, nil
794✔
2806
}
2807

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

2816
// WitnessScriptForPath returns the witness script for the given spending path.
2817
// An error is returned if the path is unknown.
2818
func (a *AnchorScriptTree) WitnessScriptForPath(
2819
        path ScriptPath) ([]byte, error) {
15✔
2820

15✔
2821
        switch path {
15✔
2822
        case ScriptPathDelay:
×
2823
                fallthrough
×
2824
        case ScriptPathSuccess:
15✔
2825
                return a.SweepLeaf.Script, nil
15✔
2826

2827
        default:
×
2828
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2829
        }
2830
}
2831

2832
// CtrlBlockForPath returns the control block for the given spending path. For
2833
// script types that don't have a control block, nil is returned.
2834
func (a *AnchorScriptTree) CtrlBlockForPath(
2835
        path ScriptPath) (*txscript.ControlBlock, error) {
×
2836

×
2837
        switch path {
×
2838
        case ScriptPathDelay:
×
2839
                fallthrough
×
2840
        case ScriptPathSuccess:
×
2841
                return lnutils.Ptr(MakeTaprootCtrlBlock(
×
2842
                        a.SweepLeaf.Script, a.InternalKey,
×
2843
                        a.TapscriptTree,
×
2844
                )), nil
×
2845

2846
        default:
×
2847
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2848
        }
2849
}
2850

2851
// Tree returns the underlying ScriptTree of the AnchorScriptTree.
2852
func (a *AnchorScriptTree) Tree() ScriptTree {
×
2853
        return a.ScriptTree
×
2854
}
×
2855

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

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

2874
        return anchorScriptTree.TaprootKey, nil
×
2875
}
2876

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

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

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

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

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

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

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

2924
        return witnessStack, nil
2✔
2925
}
2926

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

7,866✔
3047
        tweakScalar.Add(&basePriv.Key)
7,866✔
3048

7,866✔
3049
        return &btcec.PrivateKey{Key: *tweakScalar}
7,866✔
3050
}
7,866✔
3051

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

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

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

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

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

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

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

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

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

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

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

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

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

3166
// ComputeCommitmentPoint generates a commitment point given a commitment
3167
// secret. The commitment point for each state is used to randomize each key in
3168
// the key-ring and also to used as a tweak to derive new public+private keys
3169
// for the state.
3170
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
10,114✔
3171
        _, pubKey := btcec.PrivKeyFromBytes(commitSecret)
10,114✔
3172
        return pubKey
10,114✔
3173
}
10,114✔
3174

3175
// ScriptIsOpReturn returns true if the passed script is an OP_RETURN script.
3176
//
3177
// Lifted from the txscript package:
3178
// https://github.com/btcsuite/btcd/blob/cc26860b40265e1332cca8748c5dbaf3c81cc094/txscript/standard.go#L493-L526.
3179
//
3180
//nolint:ll
3181
func ScriptIsOpReturn(script []byte) bool {
58✔
3182
        // A null script is of the form:
58✔
3183
        //  OP_RETURN <optional data>
58✔
3184
        //
58✔
3185
        // Thus, it can either be a single OP_RETURN or an OP_RETURN followed by
58✔
3186
        // a data push up to MaxDataCarrierSize bytes.
58✔
3187

58✔
3188
        // The script can't possibly be a null data script if it doesn't start
58✔
3189
        // with OP_RETURN.  Fail fast to avoid more work below.
58✔
3190
        if len(script) < 1 || script[0] != txscript.OP_RETURN {
106✔
3191
                return false
48✔
3192
        }
48✔
3193

3194
        // Single OP_RETURN.
3195
        if len(script) == 1 {
14✔
3196
                return true
4✔
3197
        }
4✔
3198

3199
        // OP_RETURN followed by data push up to MaxDataCarrierSize bytes.
3200
        tokenizer := txscript.MakeScriptTokenizer(0, script[1:])
6✔
3201

6✔
3202
        return tokenizer.Next() && tokenizer.Done() &&
6✔
3203
                (txscript.IsSmallInt(tokenizer.Opcode()) ||
6✔
3204
                        tokenizer.Opcode() <= txscript.OP_PUSHDATA4) &&
6✔
3205
                len(tokenizer.Data()) <= txscript.MaxDataCarrierSize
6✔
3206
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc