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

lightningnetwork / lnd / 14050094244

25 Mar 2025 02:12AM UTC coverage: 68.947% (-0.05%) from 68.992%
14050094244

Pull #9639

github

web-flow
Merge 495db5571 into 67d2eac43
Pull Request #9639: input: update taproot scripts to add an option for the miniscript compat versions from latest spec

356 of 393 new or added lines in 2 files covered. (90.59%)

68 existing lines in 19 files now uncovered.

132747 of 192536 relevant lines covered (68.95%)

22244.69 hits per line

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

83.93
/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 {
87✔
39
        pubBytes, err := hex.DecodeString(pubStr)
87✔
40
        if err != nil {
87✔
41
                panic(err)
×
42
        }
43

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

49
        return *pub
87✔
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) {
106✔
80
        if len(rawSig) == schnorr.SignatureSize {
117✔
81
                return schnorr.ParseSignature(rawSig)
11✔
82
        }
11✔
83

84
        return ecdsa.ParseDERSignature(rawSig)
98✔
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) {
28,543✔
90
        scriptHash := sha256.Sum256(witnessScript)
28,543✔
91
        return txscript.ScriptTemplate(
28,543✔
92
                `OP_0 {{ hex .ScriptHash }}`,
28,543✔
93
                txscript.WithScriptTemplateParams(TemplateParams{
28,543✔
94
                        "ScriptHash": scriptHash[:],
28,543✔
95
                }),
28,543✔
96
        )
28,543✔
97
}
28,543✔
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) {
36✔
103
        pkhash := btcutil.Hash160(pubkey)
36✔
104
        return txscript.ScriptTemplate(
36✔
105
                `OP_0 {{ hex .PKHash }}`,
36✔
106
                txscript.WithScriptTemplateParams(TemplateParams{
36✔
107
                        "PKHash": pkhash,
36✔
108
                }),
36✔
109
        )
36✔
110
}
36✔
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) {
6✔
115
        scriptHash := btcutil.Hash160(script)
6✔
116
        return txscript.ScriptTemplate(
6✔
117
                `OP_HASH160 {{ hex .ScriptHash }} OP_EQUAL`,
6✔
118
                txscript.WithScriptTemplateParams(TemplateParams{
6✔
119
                        "ScriptHash": scriptHash,
6✔
120
                }),
6✔
121
        )
6✔
122
}
6✔
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) {
5✔
127
        pkHash := btcutil.Hash160(pubkey)
5✔
128
        return txscript.ScriptTemplate(
5✔
129
                `OP_DUP OP_HASH160 {{ hex .pkh }} OP_EQUALVERIFY OP_CHECKSIG`,
5✔
130
                txscript.WithScriptTemplateParams(TemplateParams{
5✔
131
                        "pkh": pkHash,
5✔
132
                }),
5✔
133
        )
5✔
134
}
5✔
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) {
486✔
139
        witnessScript := make([]byte, 40)
486✔
140
        return txscript.ScriptTemplate(
486✔
141
                `OP_0 {{ hex .WitnessScript }}`,
486✔
142
                txscript.WithScriptTemplateParams(TemplateParams{
486✔
143
                        "WitnessScript": witnessScript,
486✔
144
                }),
486✔
145
        )
486✔
146
}
486✔
147

148
// GenMultiSigScript generates the non-p2sh'd multisig script for 2 of 2
149
// pubkeys.
150
func GenMultiSigScript(aPub, bPub []byte) ([]byte, error) {
1,447✔
151
        if len(aPub) != 33 || len(bPub) != 33 {
1,447✔
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 {
2,171✔
161
                aPub, bPub = bPub, aPub
724✔
162
        }
724✔
163

164
        return txscript.ScriptTemplate(
1,447✔
165
                `OP_2 {{ hex .pubA }} {{ hex .pubB }} OP_2 OP_CHECKMULTISIG`,
1,447✔
166
                txscript.WithScriptTemplateParams(TemplateParams{
1,447✔
167
                        "pubA": aPub,
1,447✔
168
                        "pubB": bPub,
1,447✔
169
                }),
1,447✔
170
        )
1,447✔
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) {
284✔
176
        // As a sanity check, ensure that the passed amount is above zero.
284✔
177
        if amt <= 0 {
284✔
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)
284✔
184
        if err != nil {
284✔
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)
284✔
191
        if err != nil {
284✔
192
                return nil, nil, err
×
193
        }
×
194

195
        return witnessScript, wire.NewTxOut(amt, pkScript), nil
284✔
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) {
87✔
203

87✔
204
        muSig2Opt := musig2.WithBIP86KeyTweak()
87✔
205
        tapscriptRoot.WhenSome(func(scriptRoot chainhash.Hash) {
110✔
206
                muSig2Opt = musig2.WithTaprootKeyTweak(scriptRoot[:])
23✔
207
        })
23✔
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(
87✔
215
                []*btcec.PublicKey{aPub, bPub}, true, muSig2Opt,
87✔
216
        )
87✔
217
        if err != nil {
87✔
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)
87✔
224
        if err != nil {
87✔
225
                return nil, nil, fmt.Errorf("unable to make taproot "+
×
226
                        "pkscript: %w", err)
×
227
        }
×
228

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

87✔
231
        // For the "witness program" we just return the raw pkScript since the
87✔
232
        // output we create can _only_ be spent with a MuSig2 signature.
87✔
233
        return pkScript, txOut, nil
87✔
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 {
149✔
240

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

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

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

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

149✔
262
        return witness
149✔
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) {
91✔
271
        found := false
91✔
272
        index := uint32(0)
91✔
273
        for i, txOut := range tx.TxOut {
216✔
274
                if bytes.Equal(txOut.PkScript, script) {
214✔
275
                        found = true
89✔
276
                        index = uint32(i)
89✔
277
                        break
89✔
278
                }
279
        }
280

281
        return found, index
91✔
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,618✔
289
        h := ripemd160.New()
8,618✔
290
        h.Write(d)
8,618✔
291
        return h.Sum(nil)
8,618✔
292
}
8,618✔
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,908✔
335

3,908✔
336
        // Build the base script template
3,908✔
337
        scriptTemplate := `
3,908✔
338
        OP_DUP OP_HASH160 {{ hex .RevKeyHash }} OP_EQUAL
3,908✔
339
        OP_IF
3,908✔
340
                OP_CHECKSIG
3,908✔
341
        OP_ELSE
3,908✔
342
                {{ hex .ReceiverKey }}
3,908✔
343
                OP_SWAP OP_SIZE 32 OP_EQUAL
3,908✔
344
                OP_NOTIF
3,908✔
345
                        OP_DROP 2 OP_SWAP {{ hex .SenderKey }} 2 OP_CHECKMULTISIG
3,908✔
346
                OP_ELSE
3,908✔
347
                        OP_HASH160 {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY
3,908✔
348
                        OP_CHECKSIG
3,908✔
349
                OP_ENDIF
3,908✔
350
        `
3,908✔
351

3,908✔
352
        // Add 1 block CSV delay if a confirmation is required.
3,908✔
353
        if confirmedSpend {
4,017✔
354
                scriptTemplate += ` OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
109✔
355
        }
109✔
356

357
        // Close out the top level if statement.
358
        scriptTemplate += ` OP_ENDIF`
3,908✔
359

3,908✔
360
        // Use the ScriptTemplate function with the properly formatted template
3,908✔
361
        return txscript.ScriptTemplate(
3,908✔
362
                scriptTemplate,
3,908✔
363
                txscript.WithScriptTemplateParams(TemplateParams{
3,908✔
364
                        "RevKeyHash":        btcutil.Hash160(revocationKey.SerializeCompressed()), //nolint:ll
3,908✔
365
                        "ReceiverKey":       receiverHtlcKey.SerializeCompressed(),                //nolint:ll
3,908✔
366
                        "SenderKey":         senderHtlcKey.SerializeCompressed(),                  //nolint:ll
3,908✔
367
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
3,908✔
368
                }),
3,908✔
369
        )
3,908✔
370
}
371

372
// SenderHtlcSpendRevokeWithKey constructs a valid witness allowing the receiver of an
373
// HTLC to claim the output with knowledge of the revocation private key in the
374
// scenario that the sender of the HTLC broadcasts a previously revoked
375
// commitment transaction. A valid spend requires knowledge of the private key
376
// that corresponds to their revocation base point and also the private key from
377
// the per commitment point, and a valid signature under the combined public
378
// key.
379
func SenderHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
380
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
5✔
381

5✔
382
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
5✔
383
        if err != nil {
5✔
384
                return nil, err
×
385
        }
×
386

387
        // The stack required to sweep a revoke HTLC output consists simply of
388
        // the exact witness stack as one of a regular p2wkh spend. The only
389
        // difference is that the keys used were derived in an adversarial
390
        // manner in order to encode the revocation contract into a sig+key
391
        // pair.
392
        witnessStack := wire.TxWitness(make([][]byte, 3))
5✔
393
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
5✔
394
        witnessStack[1] = revokeKey.SerializeCompressed()
5✔
395
        witnessStack[2] = signDesc.WitnessScript
5✔
396

5✔
397
        return witnessStack, nil
5✔
398
}
399

400
// SenderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
401
// HTLC to claim the output with knowledge of the revocation private key in the
402
// scenario that the sender of the HTLC broadcasts a previously revoked
403
// commitment transaction.  This method first derives the appropriate revocation
404
// key, and requires that the provided SignDescriptor has a local revocation
405
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
406
// respectively.
407
func SenderHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
408
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
4✔
409

4✔
410
        revokeKey, err := deriveRevokePubKey(signDesc)
4✔
411
        if err != nil {
4✔
412
                return nil, err
×
413
        }
×
414

415
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
4✔
416
}
417

418
// IsHtlcSpendRevoke is used to determine if the passed spend is spending a
419
// HTLC output using the revocation key.
420
func IsHtlcSpendRevoke(txIn *wire.TxIn, signDesc *SignDescriptor) (
421
        bool, error) {
7✔
422

7✔
423
        // For taproot channels, the revocation path only has a single witness,
7✔
424
        // as that's the key spend path.
7✔
425
        isTaproot := txscript.IsPayToTaproot(signDesc.Output.PkScript)
7✔
426
        if isTaproot {
10✔
427
                return len(txIn.Witness) == 1, nil
3✔
428
        }
3✔
429

430
        revokeKey, err := deriveRevokePubKey(signDesc)
4✔
431
        if err != nil {
4✔
432
                return false, err
×
433
        }
×
434

435
        if len(txIn.Witness) == 3 &&
4✔
436
                bytes.Equal(txIn.Witness[1], revokeKey.SerializeCompressed()) {
6✔
437

2✔
438
                return true, nil
2✔
439
        }
2✔
440

441
        return false, nil
2✔
442
}
443

444
// SenderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
445
// HTLC to redeem the pending output in the scenario that the sender broadcasts
446
// their version of the commitment transaction. A valid spend requires
447
// knowledge of the payment preimage, and a valid signature under the receivers
448
// public key.
449
func SenderHtlcSpendRedeem(signer Signer, signDesc *SignDescriptor,
450
        sweepTx *wire.MsgTx, paymentPreimage []byte) (wire.TxWitness, error) {
14✔
451

14✔
452
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
14✔
453
        if err != nil {
14✔
454
                return nil, err
×
455
        }
×
456

457
        // The stack required to spend this output is simply the signature
458
        // generated above under the receiver's public key, and the payment
459
        // pre-image.
460
        witnessStack := wire.TxWitness(make([][]byte, 3))
14✔
461
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
14✔
462
        witnessStack[1] = paymentPreimage
14✔
463
        witnessStack[2] = signDesc.WitnessScript
14✔
464

14✔
465
        return witnessStack, nil
14✔
466
}
467

468
// SenderHtlcSpendTimeout constructs a valid witness allowing the sender of an
469
// HTLC to activate the time locked covenant clause of a soon to be expired
470
// HTLC.  This script simply spends the multi-sig output using the
471
// pre-generated HTLC timeout transaction.
472
func SenderHtlcSpendTimeout(receiverSig Signature,
473
        receiverSigHash txscript.SigHashType, signer Signer,
474
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx) (
475
        wire.TxWitness, error) {
56✔
476

56✔
477
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
56✔
478
        if err != nil {
56✔
479
                return nil, err
×
480
        }
×
481

482
        // We place a zero as the first item of the evaluated witness stack in
483
        // order to force Script execution to the HTLC timeout clause. The
484
        // second zero is required to consume the extra pop due to a bug in the
485
        // original OP_CHECKMULTISIG.
486
        witnessStack := wire.TxWitness(make([][]byte, 5))
56✔
487
        witnessStack[0] = nil
56✔
488
        witnessStack[1] = append(receiverSig.Serialize(), byte(receiverSigHash))
56✔
489
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
56✔
490
        witnessStack[3] = nil
56✔
491
        witnessStack[4] = signDesc.WitnessScript
56✔
492

56✔
493
        return witnessStack, nil
56✔
494
}
495

496
// SenderHTLCTapLeafTimeout returns the full tapscript leaf for the timeout
497
// path of the sender HTLC. This is a small script that allows the sender to
498
// timeout the HTLC after a period of time:
499
//
500
//        <local_key> OP_CHECKSIGVERIFY
501
//        <remote_key> OP_CHECKSIG
502
func SenderHTLCTapLeafTimeout(senderHtlcKey,
503
        receiverHtlcKey *btcec.PublicKey,
504
        _ ...TaprootScriptOpt) (txscript.TapLeaf, error) {
101✔
505

101✔
506
        timeoutLeafScript, err := txscript.ScriptTemplate(
101✔
507
                `
101✔
508
                {{ hex .SenderKey }} OP_CHECKSIGVERIFY
101✔
509
                {{ hex .ReceiverKey }} OP_CHECKSIG`,
101✔
510
                txscript.WithScriptTemplateParams(TemplateParams{
101✔
511
                        "SenderKey":   schnorr.SerializePubKey(senderHtlcKey),
101✔
512
                        "ReceiverKey": schnorr.SerializePubKey(receiverHtlcKey),
101✔
513
                }),
101✔
514
        )
101✔
515
        if err != nil {
101✔
516
                return txscript.TapLeaf{}, err
×
517
        }
×
518

519
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
101✔
520
}
521

522
// SenderHTLCTapLeafSuccess returns the full tapscript leaf for the success
523
// path of the sender HTLC. This is a small script that allows the receiver to
524
// redeem the HTLC with a pre-image:
525
//
526
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
527
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
528
//        <remote_htlcpubkey> OP_CHECKSIG
529
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
530
func SenderHTLCTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
531
        paymentHash []byte, opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
101✔
532

101✔
533
        opt := defaultTaprootScriptOpt()
101✔
534
        for _, o := range opts {
101✔
NEW
535
                o(opt)
×
NEW
536
        }
×
537

538
        var scriptTemplate string
101✔
539
        switch {
101✔
540
        case !opt.prodScript:
101✔
541
                scriptTemplate = `
101✔
542
                        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 
101✔
543
                        {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY 
101✔
544
                        {{ hex .ReceiverKey }} OP_CHECKSIG 
101✔
545
                        OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
101✔
NEW
546
        default:
×
NEW
547
                scriptTemplate = `
×
NEW
548
                        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 
×
NEW
549
                        {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY 
×
NEW
550
                        {{ hex .ReceiverKey }} OP_CHECKSIGVERIFY
×
NEW
551
                        OP_1 OP_CHECKSEQUENCEVERIFY`
×
552
        }
553

554
        successLeafScript, err := txscript.ScriptTemplate(
101✔
555
                scriptTemplate,
101✔
556
                txscript.WithScriptTemplateParams(TemplateParams{
101✔
557
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
101✔
558
                        "ReceiverKey": schnorr.SerializePubKey(
101✔
559
                                receiverHtlcKey,
101✔
560
                        ),
101✔
561
                }),
101✔
562
        )
101✔
563
        if err != nil {
101✔
564
                return txscript.TapLeaf{}, err
×
565
        }
×
566

567
        return txscript.NewBaseTapLeaf(successLeafScript), nil
101✔
568
}
569

570
// htlcType is an enum value that denotes what type of HTLC script this is.
571
type htlcType uint8
572

573
const (
574
        // htlcLocalIncoming represents an incoming HTLC on the local
575
        // commitment transaction.
576
        htlcLocalIncoming htlcType = iota
577

578
        // htlcLocalOutgoing represents an outgoing HTLC on the local
579
        // commitment transaction.
580
        htlcLocalOutgoing
581

582
        // htlcRemoteIncoming represents an incoming HTLC on the remote
583
        // commitment transaction.
584
        htlcRemoteIncoming
585

586
        // htlcRemoteOutgoing represents an outgoing HTLC on the remote
587
        // commitment transaction.
588
        htlcRemoteOutgoing
589
)
590

591
// HtlcScriptTree holds the taproot output key, as well as the two script path
592
// leaves that every taproot HTLC script depends on.
593
type HtlcScriptTree struct {
594
        ScriptTree
595

596
        // SuccessTapLeaf is the tapleaf for the redemption path.
597
        SuccessTapLeaf txscript.TapLeaf
598

599
        // TimeoutTapLeaf is the tapleaf for the timeout path.
600
        TimeoutTapLeaf txscript.TapLeaf
601

602
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
603
        // HTLC script tree with new spend paths, or just as extra commitment
604
        // space. When present, this leaf will always be in the right-most area
605
        // of the tapscript tree.
606
        AuxLeaf AuxTapLeaf
607

608
        // htlcType is the type of HTLC script this is.
609
        htlcType htlcType
610
}
611

612
// WitnessScriptToSign returns the witness script that we'll use when signing
613
// for the remote party, and also verifying signatures on our transactions. As
614
// an example, when we create an outgoing HTLC for the remote party, we want to
615
// sign the success path for them, so we'll return the success path leaf.
616
func (h *HtlcScriptTree) WitnessScriptToSign() []byte {
196✔
617
        switch h.htlcType {
196✔
618
        // For incoming HLTCs on our local commitment, we care about verifying
619
        // the success path.
620
        case htlcLocalIncoming:
51✔
621
                return h.SuccessTapLeaf.Script
51✔
622

623
        // For incoming HTLCs on the remote party's commitment, we want to sign
624
        // the timeout path for them.
625
        case htlcRemoteIncoming:
47✔
626
                return h.TimeoutTapLeaf.Script
47✔
627

628
        // For outgoing HTLCs on our local commitment, we want to verify the
629
        // timeout path.
630
        case htlcLocalOutgoing:
47✔
631
                return h.TimeoutTapLeaf.Script
47✔
632

633
        // For outgoing HTLCs on the remote party's commitment, we want to sign
634
        // the success path for them.
635
        case htlcRemoteOutgoing:
60✔
636
                return h.SuccessTapLeaf.Script
60✔
637

638
        default:
×
639
                panic(fmt.Sprintf("unknown htlc type: %v", h.htlcType))
×
640
        }
641
}
642

643
// WitnessScriptForPath returns the witness script for the given spending path.
644
// An error is returned if the path is unknown.
645
func (h *HtlcScriptTree) WitnessScriptForPath(path ScriptPath) ([]byte, error) {
11✔
646
        switch path {
11✔
647
        case ScriptPathSuccess:
7✔
648
                return h.SuccessTapLeaf.Script, nil
7✔
649
        case ScriptPathTimeout:
7✔
650
                return h.TimeoutTapLeaf.Script, nil
7✔
651
        default:
×
652
                return nil, fmt.Errorf("unknown script path: %v", path)
×
653
        }
654
}
655

656
// CtrlBlockForPath returns the control block for the given spending path. For
657
// script types that don't have a control block, nil is returned.
658
func (h *HtlcScriptTree) CtrlBlockForPath(
659
        path ScriptPath) (*txscript.ControlBlock, error) {
3✔
660

3✔
661
        switch path {
3✔
662
        case ScriptPathSuccess:
3✔
663
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
664
                        h.SuccessTapLeaf.Script, h.InternalKey,
3✔
665
                        h.TapscriptTree,
3✔
666
                )), nil
3✔
667
        case ScriptPathTimeout:
3✔
668
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
669
                        h.TimeoutTapLeaf.Script, h.InternalKey,
3✔
670
                        h.TapscriptTree,
3✔
671
                )), nil
3✔
672
        default:
×
673
                return nil, fmt.Errorf("unknown script path: %v", path)
×
674
        }
675
}
676

677
// Tree returns the underlying ScriptTree of the HtlcScriptTree.
678
func (h *HtlcScriptTree) Tree() ScriptTree {
×
679
        return h.ScriptTree
×
680
}
×
681

682
// A compile time check to ensure HtlcScriptTree implements the
683
// TapscriptMultiplexer interface.
684
var _ TapscriptDescriptor = (*HtlcScriptTree)(nil)
685

686
// senderHtlcTapScriptTree builds the tapscript tree which is used to anchor
687
// the HTLC key for HTLCs on the sender's commitment.
688
func senderHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
689
        revokeKey *btcec.PublicKey, payHash []byte, hType htlcType,
690
        auxLeaf AuxTapLeaf,
691
        opts ...TaprootScriptOpt) (*HtlcScriptTree, error) {
101✔
692

101✔
693
        // First, we'll obtain the tap leaves for both the success and timeout
101✔
694
        // path.
101✔
695
        successTapLeaf, err := SenderHTLCTapLeafSuccess(
101✔
696
                receiverHtlcKey, payHash, opts...,
101✔
697
        )
101✔
698
        if err != nil {
101✔
699
                return nil, err
×
700
        }
×
701
        timeoutTapLeaf, err := SenderHTLCTapLeafTimeout(
101✔
702
                senderHtlcKey, receiverHtlcKey, opts...,
101✔
703
        )
101✔
704
        if err != nil {
101✔
705
                return nil, err
×
706
        }
×
707

708
        tapLeaves := []txscript.TapLeaf{successTapLeaf, timeoutTapLeaf}
101✔
709
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
102✔
710
                tapLeaves = append(tapLeaves, l)
1✔
711
        })
1✔
712

713
        // With the two leaves obtained, we'll now make the tapscript tree,
714
        // then obtain the root from that
715
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
101✔
716

101✔
717
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
101✔
718

101✔
719
        // With the tapscript root obtained, we'll tweak the revocation key
101✔
720
        // with this value to obtain the key that HTLCs will be sent to.
101✔
721
        htlcKey := txscript.ComputeTaprootOutputKey(
101✔
722
                revokeKey, tapScriptRoot[:],
101✔
723
        )
101✔
724

101✔
725
        return &HtlcScriptTree{
101✔
726
                ScriptTree: ScriptTree{
101✔
727
                        TaprootKey:    htlcKey,
101✔
728
                        TapscriptTree: tapscriptTree,
101✔
729
                        TapscriptRoot: tapScriptRoot[:],
101✔
730
                        InternalKey:   revokeKey,
101✔
731
                },
101✔
732
                SuccessTapLeaf: successTapLeaf,
101✔
733
                TimeoutTapLeaf: timeoutTapLeaf,
101✔
734
                AuxLeaf:        auxLeaf,
101✔
735
                htlcType:       hType,
101✔
736
        }, nil
101✔
737
}
738

739
// SenderHTLCScriptTaproot constructs the taproot witness program (schnorr key)
740
// for an outgoing HTLC on the sender's version of the commitment transaction.
741
// This method returns the top level tweaked public key that commits to both
742
// the script paths. This is also known as an offered HTLC.
743
//
744
// The returned key commits to a tapscript tree with two possible paths:
745
//
746
//   - Timeout path:
747
//     <local_key> OP_CHECKSIGVERIFY
748
//     <remote_key> OP_CHECKSIG
749
//
750
//   - Success path:
751
//     OP_SIZE 32 OP_EQUALVERIFY
752
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
753
//     <remote_htlcpubkey> OP_CHECKSIG
754
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
755
//
756
// The timeout path can be spent with a witness of (sender timeout):
757
//
758
//        <receiver sig> <local sig> <timeout_script> <control_block>
759
//
760
// The success path can be spent with a valid control block, and a witness of
761
// (receiver redeem):
762
//
763
//        <receiver sig> <preimage> <success_script> <control_block>
764
//
765
// The top level keyspend key is the revocation key, which allows a defender to
766
// unilaterally spend the created output.
767
func SenderHTLCScriptTaproot(senderHtlcKey, receiverHtlcKey,
768
        revokeKey *btcec.PublicKey, payHash []byte,
769
        whoseCommit lntypes.ChannelParty, auxLeaf AuxTapLeaf) (*HtlcScriptTree,
770
        error) {
101✔
771

101✔
772
        var hType htlcType
101✔
773
        if whoseCommit.IsLocal() {
152✔
774
                hType = htlcLocalOutgoing
51✔
775
        } else {
104✔
776
                hType = htlcRemoteIncoming
53✔
777
        }
53✔
778

779
        // Given all the necessary parameters, we'll return the HTLC script
780
        // tree that includes the top level output script, as well as the two
781
        // tap leaf paths.
782
        return senderHtlcTapScriptTree(
101✔
783
                senderHtlcKey, receiverHtlcKey, revokeKey, payHash, hType,
101✔
784
                auxLeaf,
101✔
785
        )
101✔
786
}
787

788
// maybeAppendSighashType appends a sighash type to the end of a signature if
789
// the sighash type isn't sighash default.
790
func maybeAppendSighash(sig Signature, sigHash txscript.SigHashType) []byte {
1,540✔
791
        sigBytes := sig.Serialize()
1,540✔
792
        if sigHash == txscript.SigHashDefault {
2,959✔
793
                return sigBytes
1,419✔
794
        }
1,419✔
795

796
        return append(sigBytes, byte(sigHash))
124✔
797
}
798

799
// SenderHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
800
// sender taproot HTLC with the pre-image. The returned witness is valid and
801
// includes the control block required to spend the output. This is the offered
802
// HTLC claimed by the remote party.
803
func SenderHTLCScriptTaprootRedeem(signer Signer, signDesc *SignDescriptor,
804
        sweepTx *wire.MsgTx, preimage []byte, revokeKey *btcec.PublicKey,
805
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
12✔
806

12✔
807
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
12✔
808
        if err != nil {
12✔
809
                return nil, err
×
810
        }
×
811

812
        // In addition to the signature and the witness/leaf script, we also
813
        // need to make a control block proof using the tapscript tree.
814
        var ctrlBlock []byte
12✔
815
        if signDesc.ControlBlock == nil {
21✔
816
                successControlBlock := MakeTaprootCtrlBlock(
9✔
817
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
9✔
818
                )
9✔
819

9✔
820
                ctrlBytes, err := successControlBlock.ToBytes()
9✔
821
                if err != nil {
9✔
822
                        return nil, err
×
823
                }
×
824

825
                ctrlBlock = ctrlBytes
9✔
826
        } else {
3✔
827
                ctrlBlock = signDesc.ControlBlock
3✔
828
        }
3✔
829

830
        // The final witness stack is:
831
        //  <receiver sig> <preimage> <success_script> <control_block>
832
        witnessStack := make(wire.TxWitness, 4)
12✔
833
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
12✔
834
        witnessStack[1] = preimage
12✔
835
        witnessStack[2] = signDesc.WitnessScript
12✔
836
        witnessStack[3] = ctrlBlock
12✔
837

12✔
838
        return witnessStack, nil
12✔
839
}
840

841
// SenderHTLCScriptTaprootTimeout creates a valid witness needed to timeout an
842
// HTLC on the sender's commitment transaction. The returned witness is valid
843
// and includes the control block required to spend the output. This is a
844
// timeout of the offered HTLC by the sender.
845
func SenderHTLCScriptTaprootTimeout(receiverSig Signature,
846
        receiverSigHash txscript.SigHashType, signer Signer,
847
        signDesc *SignDescriptor, htlcTimeoutTx *wire.MsgTx,
848
        revokeKey *btcec.PublicKey,
849
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
19✔
850

19✔
851
        sweepSig, err := signer.SignOutputRaw(htlcTimeoutTx, signDesc)
19✔
852
        if err != nil {
19✔
853
                return nil, err
×
854
        }
×
855

856
        // With the sweep signature obtained, we'll obtain the control block
857
        // proof needed to perform a valid spend for the timeout path.
858
        var ctrlBlockBytes []byte
19✔
859
        if signDesc.ControlBlock == nil {
38✔
860
                timeoutControlBlock := MakeTaprootCtrlBlock(
19✔
861
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
19✔
862
                )
19✔
863
                ctrlBytes, err := timeoutControlBlock.ToBytes()
19✔
864
                if err != nil {
19✔
865
                        return nil, err
×
866
                }
×
867

868
                ctrlBlockBytes = ctrlBytes
19✔
869
        } else {
3✔
870
                ctrlBlockBytes = signDesc.ControlBlock
3✔
871
        }
3✔
872

873
        // The final witness stack is:
874
        //  <receiver sig> <local sig> <timeout_script> <control_block>
875
        witnessStack := make(wire.TxWitness, 4)
19✔
876
        witnessStack[0] = maybeAppendSighash(receiverSig, receiverSigHash)
19✔
877
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
19✔
878
        witnessStack[2] = signDesc.WitnessScript
19✔
879
        witnessStack[3] = ctrlBlockBytes
19✔
880

19✔
881
        return witnessStack, nil
19✔
882
}
883

884
// SenderHTLCScriptTaprootRevoke creates a valid witness needed to spend the
885
// revocation path of the HTLC. This uses a plain keyspend using the specified
886
// revocation key.
887
func SenderHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
888
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
12✔
889

12✔
890
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
12✔
891
        if err != nil {
12✔
892
                return nil, err
×
893
        }
×
894

895
        // The witness stack in this case is pretty simple: we only need to
896
        // specify the signature generated.
897
        witnessStack := make(wire.TxWitness, 1)
12✔
898
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
12✔
899

12✔
900
        return witnessStack, nil
12✔
901
}
902

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

4,346✔
944
        scriptTemplate := `
4,346✔
945
        OP_DUP OP_HASH160 {{ hex .RevKeyHash }} OP_EQUAL
4,346✔
946
        OP_IF
4,346✔
947
                OP_CHECKSIG
4,346✔
948
        OP_ELSE
4,346✔
949
                {{ hex .SenderKey }}
4,346✔
950
                OP_SWAP OP_SIZE 32 OP_EQUAL
4,346✔
951
                OP_IF
4,346✔
952
                        OP_HASH160 {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY
4,346✔
953
                        OP_2 OP_SWAP {{ hex .ReceiverKey }} OP_2 OP_CHECKMULTISIG
4,346✔
954
                OP_ELSE
4,346✔
955
                        OP_DROP {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
4,346✔
956
                        OP_CHECKSIG
4,346✔
957
                OP_ENDIF
4,346✔
958
        `
4,346✔
959

4,346✔
960
        // Add 1 block CSV delay for non-revocation clauses if confirmation is
4,346✔
961
        // required.
4,346✔
962
        if confirmedSpend {
4,496✔
963
                scriptTemplate += ` OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
150✔
964
        }
150✔
965

966
        // Close out the outer if statement.
967
        scriptTemplate += ` OP_ENDIF`
4,346✔
968

4,346✔
969
        // Use the ScriptTemplate function with the properly formatted template
4,346✔
970
        return txscript.ScriptTemplate(
4,346✔
971
                scriptTemplate,
4,346✔
972
                txscript.WithScriptTemplateParams(TemplateParams{
4,346✔
973
                        "RevKeyHash": btcutil.Hash160(
4,346✔
974
                                revocationKey.SerializeCompressed(),
4,346✔
975
                        ),
4,346✔
976
                        "SenderKey":         senderHtlcKey.SerializeCompressed(),   //nolint:ll
4,346✔
977
                        "ReceiverKey":       receiverHtlcKey.SerializeCompressed(), //nolint:ll
4,346✔
978
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
4,346✔
979
                        "CltvExpiry":        int64(cltvExpiry),
4,346✔
980
                }),
4,346✔
981
        )
4,346✔
982
}
983

984
// ReceiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
985
// an HTLC to redeem the conditional payment in the event that their commitment
986
// transaction is broadcast. This clause transitions the state of the HLTC
987
// output into the delay+claim state by activating the off-chain covenant bound
988
// by the 2-of-2 multi-sig output. The HTLC success timeout transaction being
989
// signed has a relative timelock delay enforced by its sequence number. This
990
// delay give the sender of the HTLC enough time to revoke the output if this
991
// is a breach commitment transaction.
992
func ReceiverHtlcSpendRedeem(senderSig Signature,
993
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
994
        signer Signer, signDesc *SignDescriptor, htlcSuccessTx *wire.MsgTx) (
995
        wire.TxWitness, error) {
61✔
996

61✔
997
        // First, we'll generate a signature for the HTLC success transaction.
61✔
998
        // The signDesc should be signing with the public key used as the
61✔
999
        // receiver's public key and also the correct single tweak.
61✔
1000
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
61✔
1001
        if err != nil {
61✔
1002
                return nil, err
×
1003
        }
×
1004

1005
        // The final witness stack is used the provide the script with the
1006
        // payment pre-image, and also execute the multi-sig clause after the
1007
        // pre-images matches. We add a nil item at the bottom of the stack in
1008
        // order to consume the extra pop within OP_CHECKMULTISIG.
1009
        witnessStack := wire.TxWitness(make([][]byte, 5))
61✔
1010
        witnessStack[0] = nil
61✔
1011
        witnessStack[1] = append(senderSig.Serialize(), byte(senderSigHash))
61✔
1012
        witnessStack[2] = append(sweepSig.Serialize(), byte(signDesc.HashType))
61✔
1013
        witnessStack[3] = paymentPreimage
61✔
1014
        witnessStack[4] = signDesc.WitnessScript
61✔
1015

61✔
1016
        return witnessStack, nil
61✔
1017
}
1018

1019
// ReceiverHtlcSpendRevokeWithKey constructs a valid witness allowing the sender of an
1020
// HTLC within a previously revoked commitment transaction to re-claim the
1021
// pending funds in the case that the receiver broadcasts this revoked
1022
// commitment transaction.
1023
func ReceiverHtlcSpendRevokeWithKey(signer Signer, signDesc *SignDescriptor,
1024
        revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx) (wire.TxWitness, error) {
22✔
1025

22✔
1026
        // First, we'll generate a signature for the sweep transaction.  The
22✔
1027
        // signDesc should be signing with the public key used as the fully
22✔
1028
        // derived revocation public key and also the correct double tweak
22✔
1029
        // value.
22✔
1030
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
22✔
1031
        if err != nil {
22✔
1032
                return nil, err
×
1033
        }
×
1034

1035
        // We place a zero, then one as the first items in the evaluated
1036
        // witness stack in order to force script execution to the HTLC
1037
        // revocation clause.
1038
        witnessStack := wire.TxWitness(make([][]byte, 3))
22✔
1039
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
22✔
1040
        witnessStack[1] = revokeKey.SerializeCompressed()
22✔
1041
        witnessStack[2] = signDesc.WitnessScript
22✔
1042

22✔
1043
        return witnessStack, nil
22✔
1044
}
1045

1046
func deriveRevokePubKey(signDesc *SignDescriptor) (*btcec.PublicKey, error) {
29✔
1047
        if signDesc.KeyDesc.PubKey == nil {
29✔
1048
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
1049
                        "KeyDesc pubkey")
×
1050
        }
×
1051

1052
        // Derive the revocation key using the local revocation base point and
1053
        // commitment point.
1054
        revokeKey := DeriveRevocationPubkey(
29✔
1055
                signDesc.KeyDesc.PubKey,
29✔
1056
                signDesc.DoubleTweak.PubKey(),
29✔
1057
        )
29✔
1058

29✔
1059
        return revokeKey, nil
29✔
1060
}
1061

1062
// ReceiverHtlcSpendRevoke constructs a valid witness allowing the sender of an
1063
// HTLC within a previously revoked commitment transaction to re-claim the
1064
// pending funds in the case that the receiver broadcasts this revoked
1065
// commitment transaction. This method first derives the appropriate revocation
1066
// key, and requires that the provided SignDescriptor has a local revocation
1067
// basepoint and commitment secret in the PubKey and DoubleTweak fields,
1068
// respectively.
1069
func ReceiverHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1070
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
21✔
1071

21✔
1072
        revokeKey, err := deriveRevokePubKey(signDesc)
21✔
1073
        if err != nil {
21✔
1074
                return nil, err
×
1075
        }
×
1076

1077
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
21✔
1078
}
1079

1080
// ReceiverHtlcSpendTimeout constructs a valid witness allowing the sender of
1081
// an HTLC to recover the pending funds after an absolute timeout in the
1082
// scenario that the receiver of the HTLC broadcasts their version of the
1083
// commitment transaction. If the caller has already set the lock time on the
1084
// spending transaction, than a value of -1 can be passed for the cltvExpiry
1085
// value.
1086
//
1087
// NOTE: The target input of the passed transaction MUST NOT have a final
1088
// sequence number. Otherwise, the OP_CHECKLOCKTIMEVERIFY check will fail.
1089
func ReceiverHtlcSpendTimeout(signer Signer, signDesc *SignDescriptor,
1090
        sweepTx *wire.MsgTx, cltvExpiry int32) (wire.TxWitness, error) {
11✔
1091

11✔
1092
        // If the caller set a proper timeout value, then we'll apply it
11✔
1093
        // directly to the transaction.
11✔
1094
        if cltvExpiry != -1 {
19✔
1095
                // The HTLC output has an absolute time period before we are
8✔
1096
                // permitted to recover the pending funds. Therefore we need to
8✔
1097
                // set the locktime on this sweeping transaction in order to
8✔
1098
                // pass Script verification.
8✔
1099
                sweepTx.LockTime = uint32(cltvExpiry)
8✔
1100
        }
8✔
1101

1102
        // With the lock time on the transaction set, we'll not generate a
1103
        // signature for the sweep transaction. The passed sign descriptor
1104
        // should be created using the raw public key of the sender (w/o the
1105
        // single tweak applied), and the single tweak set to the proper value
1106
        // taking into account the current state's point.
1107
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
11✔
1108
        if err != nil {
11✔
1109
                return nil, err
×
1110
        }
×
1111

1112
        witnessStack := wire.TxWitness(make([][]byte, 3))
11✔
1113
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
11✔
1114
        witnessStack[1] = nil
11✔
1115
        witnessStack[2] = signDesc.WitnessScript
11✔
1116

11✔
1117
        return witnessStack, nil
11✔
1118
}
1119

1120
// ReceiverHtlcTapLeafTimeout returns the full tapscript leaf for the timeout
1121
// path of the sender HTLC. This is a small script that allows the sender
1122
// timeout the HTLC after expiry:
1123
//
1124
//        <sender_htlcpubkey> OP_CHECKSIG
1125
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
1126
//        <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1127
func ReceiverHtlcTapLeafTimeout(senderHtlcKey *btcec.PublicKey,
1128
        cltvExpiry uint32, opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
118✔
1129

118✔
1130
        opt := defaultTaprootScriptOpt()
118✔
1131
        for _, o := range opts {
118✔
NEW
1132
                o(opt)
×
NEW
1133
        }
×
1134

1135
        var scriptTemplate string
118✔
1136
        switch {
118✔
1137
        case !opt.prodScript:
118✔
1138
                scriptTemplate = `
118✔
1139
                {{ hex .SenderKey }} OP_CHECKSIG 
118✔
1140
                OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP 
118✔
1141
                {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP`
118✔
1142

NEW
1143
        default:
×
NEW
1144
                scriptTemplate = `
×
NEW
1145
                {{ hex .SenderKey }} OP_CHECKSIGVERIFY
×
NEW
1146
                OP_1 OP_CHECKSEQUENCEVERIFY OP_VERIFY
×
NEW
1147
                {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY`
×
1148
        }
1149

1150
        // The first part of the script will verify a signature from the sender
1151
        // authorizing the spend (the timeout). The second portion will ensure
1152
        // that the CLTV expiry on the spending transaction is correct.
1153
        timeoutLeafScript, err := txscript.ScriptTemplate(
118✔
1154
                scriptTemplate,
118✔
1155
                txscript.WithScriptTemplateParams(TemplateParams{
118✔
1156
                        "SenderKey":  schnorr.SerializePubKey(senderHtlcKey),
118✔
1157
                        "CltvExpiry": int64(cltvExpiry),
118✔
1158
                }),
118✔
1159
        )
118✔
1160
        if err != nil {
118✔
1161
                return txscript.TapLeaf{}, err
×
1162
        }
×
1163

1164
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
118✔
1165
}
1166

1167
// ReceiverHtlcTapLeafSuccess returns the full tapscript leaf for the success
1168
// path for an HTLC on the receiver's commitment transaction. This script
1169
// allows the receiver to redeem an HTLC with knowledge of the preimage:
1170
//
1171
//        OP_SIZE 32 OP_EQUALVERIFY OP_HASH160
1172
//        <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1173
//        <receiver_htlcpubkey> OP_CHECKSIGVERIFY
1174
//        <sender_htlcpubkey> OP_CHECKSIG
1175
func ReceiverHtlcTapLeafSuccess(receiverHtlcKey *btcec.PublicKey,
1176
        senderHtlcKey *btcec.PublicKey,
1177
        paymentHash []byte,
1178
        opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
118✔
1179

118✔
1180
        // Check that the pre-image is 32 bytes as required. We also check that
118✔
1181
        // the specified pre-image matches what we hard code into the script.
118✔
1182
        // Finally, verify the "2-of-2" multi-sig that requires both parties to
118✔
1183
        // sign off.
118✔
1184
        successLeafScript, err := txscript.ScriptTemplate(
118✔
1185
                `
118✔
1186
                OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 
118✔
1187
                {{ hex .PaymentHashRipemd }} OP_EQUALVERIFY 
118✔
1188
                {{ hex .ReceiverKey }} OP_CHECKSIGVERIFY 
118✔
1189
                {{ hex .SenderKey }} OP_CHECKSIG`,
118✔
1190
                txscript.WithScriptTemplateParams(TemplateParams{
118✔
1191
                        "PaymentHashRipemd": Ripemd160H(paymentHash),
118✔
1192
                        "ReceiverKey": schnorr.SerializePubKey(
118✔
1193
                                receiverHtlcKey,
118✔
1194
                        ),
118✔
1195
                        "SenderKey": schnorr.SerializePubKey(senderHtlcKey),
118✔
1196
                }),
118✔
1197
        )
118✔
1198
        if err != nil {
118✔
1199
                return txscript.TapLeaf{}, err
×
1200
        }
×
1201

1202
        return txscript.NewBaseTapLeaf(successLeafScript), nil
118✔
1203
}
1204

1205
// receiverHtlcTapScriptTree builds the tapscript tree which is used to anchor
1206
// the HTLC key for HTLCs on the receiver's commitment.
1207
func receiverHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
1208
        revokeKey *btcec.PublicKey, payHash []byte, cltvExpiry uint32,
1209
        hType htlcType, auxLeaf AuxTapLeaf,
1210
        opts ...TaprootScriptOpt) (*HtlcScriptTree, error) {
118✔
1211

118✔
1212
        // First, we'll obtain the tap leaves for both the success and timeout
118✔
1213
        // path.
118✔
1214
        successTapLeaf, err := ReceiverHtlcTapLeafSuccess(
118✔
1215
                receiverHtlcKey, senderHtlcKey, payHash, opts...,
118✔
1216
        )
118✔
1217
        if err != nil {
118✔
1218
                return nil, err
×
1219
        }
×
1220
        timeoutTapLeaf, err := ReceiverHtlcTapLeafTimeout(
118✔
1221
                senderHtlcKey, cltvExpiry, opts...,
118✔
1222
        )
118✔
1223
        if err != nil {
118✔
1224
                return nil, err
×
1225
        }
×
1226

1227
        tapLeaves := []txscript.TapLeaf{timeoutTapLeaf, successTapLeaf}
118✔
1228
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
119✔
1229
                tapLeaves = append(tapLeaves, l)
1✔
1230
        })
1✔
1231

1232
        // With the two leaves obtained, we'll now make the tapscript tree,
1233
        // then obtain the root from that
1234
        tapscriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
118✔
1235

118✔
1236
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
118✔
1237

118✔
1238
        // With the tapscript root obtained, we'll tweak the revocation key
118✔
1239
        // with this value to obtain the key that HTLCs will be sent to.
118✔
1240
        htlcKey := txscript.ComputeTaprootOutputKey(
118✔
1241
                revokeKey, tapScriptRoot[:],
118✔
1242
        )
118✔
1243

118✔
1244
        return &HtlcScriptTree{
118✔
1245
                ScriptTree: ScriptTree{
118✔
1246
                        TaprootKey:    htlcKey,
118✔
1247
                        TapscriptTree: tapscriptTree,
118✔
1248
                        TapscriptRoot: tapScriptRoot[:],
118✔
1249
                        InternalKey:   revokeKey,
118✔
1250
                },
118✔
1251
                SuccessTapLeaf: successTapLeaf,
118✔
1252
                TimeoutTapLeaf: timeoutTapLeaf,
118✔
1253
                AuxLeaf:        auxLeaf,
118✔
1254
                htlcType:       hType,
118✔
1255
        }, nil
118✔
1256
}
1257

1258
// ReceiverHTLCScriptTaproot constructs the taproot witness program (schnor
1259
// key) for an incoming HTLC on the receiver's version of the commitment
1260
// transaction. This method returns the top level tweaked public key that
1261
// commits to both the script paths. From the PoV of the receiver, this is an
1262
// accepted HTLC.
1263
//
1264
// The returned key commits to a tapscript tree with two possible paths:
1265
//
1266
//   - The timeout path:
1267
//     <remote_htlcpubkey> OP_CHECKSIG
1268
//     1 OP_CHECKSEQUENCEVERIFY OP_DROP
1269
//     <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
1270
//
1271
//   - Success path:
1272
//     OP_SIZE 32 OP_EQUALVERIFY
1273
//     OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
1274
//     <local_htlcpubkey> OP_CHECKSIGVERIFY
1275
//     <remote_htlcpubkey> OP_CHECKSIG
1276
//
1277
// The timeout path can be spent with a witness of:
1278
//   - <sender sig> <timeout_script> <control_block>
1279
//
1280
// The success path can be spent with a witness of:
1281
//   - <sender sig> <receiver sig> <preimage> <success_script> <control_block>
1282
//
1283
// The top level keyspend key is the revocation key, which allows a defender to
1284
// unilaterally spend the created output. Both the final output key as well as
1285
// the tap leaf are returned.
1286
func ReceiverHTLCScriptTaproot(cltvExpiry uint32,
1287
        senderHtlcKey, receiverHtlcKey, revocationKey *btcec.PublicKey,
1288
        payHash []byte, whoseCommit lntypes.ChannelParty,
1289
        auxLeaf AuxTapLeaf) (*HtlcScriptTree, error) {
118✔
1290

118✔
1291
        var hType htlcType
118✔
1292
        if whoseCommit.IsLocal() {
173✔
1293
                hType = htlcLocalIncoming
55✔
1294
        } else {
121✔
1295
                hType = htlcRemoteOutgoing
66✔
1296
        }
66✔
1297

1298
        // Given all the necessary parameters, we'll return the HTLC script
1299
        // tree that includes the top level output script, as well as the two
1300
        // tap leaf paths.
1301
        return receiverHtlcTapScriptTree(
118✔
1302
                senderHtlcKey, receiverHtlcKey, revocationKey, payHash,
118✔
1303
                cltvExpiry, hType, auxLeaf,
118✔
1304
        )
118✔
1305
}
1306

1307
// ReceiverHTLCScriptTaprootRedeem creates a valid witness needed to redeem a
1308
// receiver taproot HTLC with the pre-image. The returned witness is valid and
1309
// includes the control block required to spend the output.
1310
func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
1311
        senderSigHash txscript.SigHashType, paymentPreimage []byte,
1312
        signer Signer, signDesc *SignDescriptor,
1313
        htlcSuccessTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1314
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
23✔
1315

23✔
1316
        // First, we'll generate a signature for the HTLC success transaction.
23✔
1317
        // The signDesc should be signing with the public key used as the
23✔
1318
        // receiver's public key and also the correct single tweak.
23✔
1319
        sweepSig, err := signer.SignOutputRaw(htlcSuccessTx, signDesc)
23✔
1320
        if err != nil {
23✔
1321
                return nil, err
×
1322
        }
×
1323

1324
        // In addition to the signature and the witness/leaf script, we also
1325
        // need to make a control block proof using the tapscript tree.
1326
        var ctrlBlock []byte
23✔
1327
        if signDesc.ControlBlock == nil {
46✔
1328
                redeemControlBlock := MakeTaprootCtrlBlock(
23✔
1329
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
23✔
1330
                )
23✔
1331
                ctrlBytes, err := redeemControlBlock.ToBytes()
23✔
1332
                if err != nil {
23✔
1333
                        return nil, err
×
1334
                }
×
1335

1336
                ctrlBlock = ctrlBytes
23✔
1337
        } else {
3✔
1338
                ctrlBlock = signDesc.ControlBlock
3✔
1339
        }
3✔
1340

1341
        // The final witness stack is:
1342
        //  * <sender sig> <receiver sig> <preimage> <success_script>
1343
        //    <control_block>
1344
        witnessStack := wire.TxWitness(make([][]byte, 5))
23✔
1345
        witnessStack[0] = maybeAppendSighash(senderSig, senderSigHash)
23✔
1346
        witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
23✔
1347
        witnessStack[2] = paymentPreimage
23✔
1348
        witnessStack[3] = signDesc.WitnessScript
23✔
1349
        witnessStack[4] = ctrlBlock
23✔
1350

23✔
1351
        return witnessStack, nil
23✔
1352
}
1353

1354
// ReceiverHTLCScriptTaprootTimeout creates a valid witness needed to timeout
1355
// an HTLC on the receiver's commitment transaction after the timeout has
1356
// elapsed.
1357
func ReceiverHTLCScriptTaprootTimeout(signer Signer, signDesc *SignDescriptor,
1358
        sweepTx *wire.MsgTx, cltvExpiry int32, revokeKey *btcec.PublicKey,
1359
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
16✔
1360

16✔
1361
        // If the caller set a proper timeout value, then we'll apply it
16✔
1362
        // directly to the transaction.
16✔
1363
        //
16✔
1364
        // TODO(roasbeef): helper func
16✔
1365
        if cltvExpiry != -1 {
29✔
1366
                // The HTLC output has an absolute time period before we are
13✔
1367
                // permitted to recover the pending funds. Therefore we need to
13✔
1368
                // set the locktime on this sweeping transaction in order to
13✔
1369
                // pass Script verification.
13✔
1370
                sweepTx.LockTime = uint32(cltvExpiry)
13✔
1371
        }
13✔
1372

1373
        // With the lock time on the transaction set, we'll now generate a
1374
        // signature for the sweep transaction. The passed sign descriptor
1375
        // should be created using the raw public key of the sender (w/o the
1376
        // single tweak applied), and the single tweak set to the proper value
1377
        // taking into account the current state's point.
1378
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
16✔
1379
        if err != nil {
16✔
1380
                return nil, err
×
1381
        }
×
1382

1383
        // In addition to the signature and the witness/leaf script, we also
1384
        // need to make a control block proof using the tapscript tree.
1385
        var ctrlBlock []byte
16✔
1386
        if signDesc.ControlBlock == nil {
29✔
1387
                timeoutControlBlock := MakeTaprootCtrlBlock(
13✔
1388
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
13✔
1389
                )
13✔
1390
                ctrlBlock, err = timeoutControlBlock.ToBytes()
13✔
1391
                if err != nil {
13✔
1392
                        return nil, err
×
1393
                }
×
1394
        } else {
3✔
1395
                ctrlBlock = signDesc.ControlBlock
3✔
1396
        }
3✔
1397

1398
        // The final witness is pretty simple, we just need to present a valid
1399
        // signature for the script, and then provide the control block.
1400
        witnessStack := make(wire.TxWitness, 3)
16✔
1401
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
16✔
1402
        witnessStack[1] = signDesc.WitnessScript
16✔
1403
        witnessStack[2] = ctrlBlock
16✔
1404

16✔
1405
        return witnessStack, nil
16✔
1406
}
1407

1408
// ReceiverHTLCScriptTaprootRevoke creates a valid witness needed to spend the
1409
// revocation path of the HTLC from the PoV of the sender (offerer) of the
1410
// HTLC. This uses a plain keyspend using the specified revocation key.
1411
func ReceiverHTLCScriptTaprootRevoke(signer Signer, signDesc *SignDescriptor,
1412
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
8✔
1413

8✔
1414
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
8✔
1415
        if err != nil {
8✔
1416
                return nil, err
×
1417
        }
×
1418

1419
        // The witness stack in this case is pretty simple: we only need to
1420
        // specify the signature generated.
1421
        witnessStack := make(wire.TxWitness, 1)
8✔
1422
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
8✔
1423

8✔
1424
        return witnessStack, nil
8✔
1425
}
1426

1427
// SecondLevelHtlcScript is the uniform script that's used as the output for
1428
// the second-level HTLC transactions. The second level transaction act as a
1429
// sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1430
// spent in a particular way, and to a particular output.
1431
//
1432
// Possible Input Scripts:
1433
//
1434
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1435
//     state:
1436
//     <revoke sig> 1
1437
//
1438
//   - To claim and HTLC output, either with a pre-image or due to a timeout:
1439
//     <delay sig> 0
1440
//
1441
// Output Script:
1442
//
1443
//         OP_IF
1444
//                <revoke key>
1445
//         OP_ELSE
1446
//                <delay in blocks>
1447
//                OP_CHECKSEQUENCEVERIFY
1448
//                OP_DROP
1449
//                <delay key>
1450
//         OP_ENDIF
1451
//         OP_CHECKSIG
1452
//
1453
// TODO(roasbeef): possible renames for second-level
1454
//   - transition?
1455
//   - covenant output
1456
func SecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1457
        csvDelay uint32) ([]byte, error) {
7,906✔
1458

7,906✔
1459
        // If this is the revocation clause for this script is to be executed,
7,906✔
1460
        // the spender will push a 1, forcing us to hit the true clause of this
7,906✔
1461
        // if statement.
7,906✔
1462
        // If this is the revocation case, then we'll push the revocation
7,906✔
1463
        // public key on the stack.
7,906✔
1464
        // Otherwise, this is either the sender or receiver of the HTLC
7,906✔
1465
        // attempting to claim the HTLC output.
7,906✔
1466
        // In order to give the other party time to execute the revocation
7,906✔
1467
        // clause above, we require a relative timeout to pass before the
7,906✔
1468
        // output can be spent.
7,906✔
1469
        // If the relative timelock passes, then we'll add the delay key to the
7,906✔
1470
        // stack to ensure that we properly authenticate the spending party.
7,906✔
1471
        // In either case, we'll ensure that only either the party possessing
7,906✔
1472
        // the revocation private key, or the delay private key is able to
7,906✔
1473
        // spend this output.
7,906✔
1474
        return txscript.ScriptTemplate(
7,906✔
1475
                `OP_IF
7,906✔
1476
                        {{ hex .RevokeKey }}
7,906✔
1477
                OP_ELSE
7,906✔
1478
                        {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP
7,906✔
1479
                        {{ hex .DelayKey }}
7,906✔
1480
                OP_ENDIF OP_CHECKSIG`,
7,906✔
1481
                txscript.WithScriptTemplateParams(TemplateParams{
7,906✔
1482
                        "RevokeKey": revocationKey.SerializeCompressed(),
7,906✔
1483
                        "CsvDelay":  int64(csvDelay),
7,906✔
1484
                        "DelayKey":  delayKey.SerializeCompressed(),
7,906✔
1485
                }),
7,906✔
1486
        )
7,906✔
1487
}
7,906✔
1488

1489
// TODO(roasbeef): move all taproot stuff to new file?
1490

1491
// TaprootSecondLevelTapLeaf constructs the tap leaf used as the sole script
1492
// path for a second level HTLC spend.
1493
//
1494
// The final script used is:
1495
//
1496
//        <local_delay_key> OP_CHECKSIG
1497
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1498
func TaprootSecondLevelTapLeaf(delayKey *btcec.PublicKey,
1499
        csvDelay uint32, opts ...TaprootScriptOpt) (txscript.TapLeaf, error) {
164✔
1500

164✔
1501
        opt := defaultTaprootScriptOpt()
164✔
1502
        for _, o := range opts {
164✔
NEW
1503
                o(opt)
×
NEW
1504
        }
×
1505

1506
        var scriptTemplate string
164✔
1507
        switch {
164✔
1508
        case !opt.prodScript:
164✔
1509
                scriptTemplate = `
164✔
1510
                {{ hex .DelayKey }} OP_CHECKSIG 
164✔
1511
                {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP`
164✔
1512

NEW
1513
        default:
×
NEW
1514
                scriptTemplate = `
×
NEW
1515
                {{ hex .DelayKey }} OP_CHECKSIGVERIFY
×
NEW
1516
                {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY`
×
1517
        }
1518

1519
        // Ensure the proper party can sign for this output.
1520
        // Assuming the above passes, then we'll now ensure that the CSV delay
1521
        // has been upheld, dropping the int we pushed on. If the sig above is
1522
        // valid, then a 1 will be left on the stack.
1523
        secondLevelLeafScript, err := txscript.ScriptTemplate(
164✔
1524
                scriptTemplate,
164✔
1525
                txscript.WithScriptTemplateParams(TemplateParams{
164✔
1526
                        "DelayKey": schnorr.SerializePubKey(delayKey),
164✔
1527
                        "CsvDelay": int64(csvDelay),
164✔
1528
                }),
164✔
1529
        )
164✔
1530
        if err != nil {
164✔
1531
                return txscript.TapLeaf{}, err
×
1532
        }
×
1533

1534
        return txscript.NewBaseTapLeaf(secondLevelLeafScript), nil
164✔
1535
}
1536

1537
// SecondLevelHtlcTapscriptTree construct the indexed tapscript tree needed to
1538
// generate the tap tweak to create the final output and also control block.
1539
func SecondLevelHtlcTapscriptTree(delayKey *btcec.PublicKey, csvDelay uint32,
1540
        auxLeaf AuxTapLeaf) (*txscript.IndexedTapScriptTree, error) {
164✔
1541

164✔
1542
        // First grab the second level leaf script we need to create the top
164✔
1543
        // level output.
164✔
1544
        secondLevelTapLeaf, err := TaprootSecondLevelTapLeaf(delayKey, csvDelay)
164✔
1545
        if err != nil {
164✔
1546
                return nil, err
×
1547
        }
×
1548

1549
        tapLeaves := []txscript.TapLeaf{secondLevelTapLeaf}
164✔
1550
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
165✔
1551
                tapLeaves = append(tapLeaves, l)
1✔
1552
        })
1✔
1553

1554
        // Now that we have the sole second level script, we can create the
1555
        // tapscript tree that commits to both the leaves.
1556
        return txscript.AssembleTaprootScriptTree(tapLeaves...), nil
164✔
1557
}
1558

1559
// TaprootSecondLevelHtlcScript is the uniform script that's used as the output
1560
// for the second-level HTLC transaction. The second level transaction acts as
1561
// an off-chain 2-of-2 covenant that can only be spent a particular way and to
1562
// a particular output.
1563
//
1564
// Possible Input Scripts:
1565
//   - revocation sig
1566
//   - <local_delay_sig>
1567
//
1568
// The script main script lets the broadcaster spend after a delay the script
1569
// path:
1570
//
1571
//        <local_delay_key> OP_CHECKSIG
1572
//        <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
1573
//
1574
// The keyspend path require knowledge of the top level revocation private key.
1575
func TaprootSecondLevelHtlcScript(revokeKey, delayKey *btcec.PublicKey,
1576
        csvDelay uint32, auxLeaf AuxTapLeaf) (*btcec.PublicKey, error) {
×
1577

×
1578
        // First, we'll make the tapscript tree that commits to the redemption
×
1579
        // path.
×
1580
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
×
1581
                delayKey, csvDelay, auxLeaf,
×
1582
        )
×
1583
        if err != nil {
×
1584
                return nil, err
×
1585
        }
×
1586

1587
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
×
1588

×
1589
        // With the tapscript root obtained, we'll tweak the revocation key
×
1590
        // with this value to obtain the key that the second level spend will
×
1591
        // create.
×
1592
        redemptionKey := txscript.ComputeTaprootOutputKey(
×
1593
                revokeKey, tapScriptRoot[:],
×
1594
        )
×
1595

×
1596
        return redemptionKey, nil
×
1597
}
1598

1599
// SecondLevelScriptTree is a tapscript tree used to spend the second level
1600
// HTLC output after the CSV delay has passed.
1601
type SecondLevelScriptTree struct {
1602
        ScriptTree
1603

1604
        // SuccessTapLeaf is the tapleaf for the redemption path.
1605
        SuccessTapLeaf txscript.TapLeaf
1606

1607
        // AuxLeaf is an optional leaf that can be used to extend the script
1608
        // tree.
1609
        AuxLeaf AuxTapLeaf
1610
}
1611

1612
// TaprootSecondLevelScriptTree constructs the tapscript tree used to spend the
1613
// second level HTLC output.
1614
func TaprootSecondLevelScriptTree(revokeKey, delayKey *btcec.PublicKey,
1615
        csvDelay uint32, auxLeaf AuxTapLeaf) (*SecondLevelScriptTree, error) {
160✔
1616

160✔
1617
        // First, we'll make the tapscript tree that commits to the redemption
160✔
1618
        // path.
160✔
1619
        tapScriptTree, err := SecondLevelHtlcTapscriptTree(
160✔
1620
                delayKey, csvDelay, auxLeaf,
160✔
1621
        )
160✔
1622
        if err != nil {
160✔
1623
                return nil, err
×
1624
        }
×
1625

1626
        // With the tree constructed, we can make the pkscript which is the
1627
        // taproot output key itself.
1628
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
160✔
1629
        outputKey := txscript.ComputeTaprootOutputKey(
160✔
1630
                revokeKey, tapScriptRoot[:],
160✔
1631
        )
160✔
1632

160✔
1633
        return &SecondLevelScriptTree{
160✔
1634
                ScriptTree: ScriptTree{
160✔
1635
                        TaprootKey:    outputKey,
160✔
1636
                        TapscriptTree: tapScriptTree,
160✔
1637
                        TapscriptRoot: tapScriptRoot[:],
160✔
1638
                        InternalKey:   revokeKey,
160✔
1639
                },
160✔
1640
                SuccessTapLeaf: tapScriptTree.LeafMerkleProofs[0].TapLeaf,
160✔
1641
                AuxLeaf:        auxLeaf,
160✔
1642
        }, nil
160✔
1643
}
1644

1645
// WitnessScriptToSign returns the witness script that we'll use when signing
1646
// for the remote party, and also verifying signatures on our transactions. As
1647
// an example, when we create an outgoing HTLC for the remote party, we want to
1648
// sign their success path.
1649
func (s *SecondLevelScriptTree) WitnessScriptToSign() []byte {
×
1650
        return s.SuccessTapLeaf.Script
×
1651
}
×
1652

1653
// WitnessScriptForPath returns the witness script for the given spending path.
1654
// An error is returned if the path is unknown.
1655
func (s *SecondLevelScriptTree) WitnessScriptForPath(
1656
        path ScriptPath) ([]byte, error) {
11✔
1657

11✔
1658
        switch path {
11✔
1659
        case ScriptPathDelay:
×
1660
                fallthrough
×
1661
        case ScriptPathSuccess:
11✔
1662
                return s.SuccessTapLeaf.Script, nil
11✔
1663

1664
        default:
×
1665
                return nil, fmt.Errorf("unknown script path: %v", path)
×
1666
        }
1667
}
1668

1669
// CtrlBlockForPath returns the control block for the given spending path. For
1670
// script types that don't have a control block, nil is returned.
1671
func (s *SecondLevelScriptTree) CtrlBlockForPath(
1672
        path ScriptPath) (*txscript.ControlBlock, error) {
11✔
1673

11✔
1674
        switch path {
11✔
1675
        case ScriptPathDelay:
×
1676
                fallthrough
×
1677
        case ScriptPathSuccess:
11✔
1678
                return lnutils.Ptr(MakeTaprootCtrlBlock(
11✔
1679
                        s.SuccessTapLeaf.Script, s.InternalKey,
11✔
1680
                        s.TapscriptTree,
11✔
1681
                )), nil
11✔
1682

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

1688
// Tree returns the underlying ScriptTree of the SecondLevelScriptTree.
1689
func (s *SecondLevelScriptTree) Tree() ScriptTree {
×
1690
        return s.ScriptTree
×
1691
}
×
1692

1693
// A compile time check to ensure SecondLevelScriptTree implements the
1694
// TapscriptDescriptor interface.
1695
var _ TapscriptDescriptor = (*SecondLevelScriptTree)(nil)
1696

1697
// TaprootHtlcSpendRevoke spends a second-level HTLC output via the revocation
1698
// path. This uses the top level keyspend path to redeem the contested output.
1699
//
1700
// The passed SignDescriptor MUST have the proper witness script and also the
1701
// proper top-level tweak derived from the tapscript tree for the second level
1702
// output.
1703
func TaprootHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1704
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
9✔
1705

9✔
1706
        // We don't need any spacial modifications to the transaction as this
9✔
1707
        // is just sweeping a revoked HTLC output. So we'll generate a regular
9✔
1708
        // schnorr signature.
9✔
1709
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
9✔
1710
        if err != nil {
9✔
1711
                return nil, err
×
1712
        }
×
1713

1714
        // The witness stack in this case is pretty simple: we only need to
1715
        // specify the signature generated.
1716
        witnessStack := make(wire.TxWitness, 1)
9✔
1717
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
9✔
1718

9✔
1719
        return witnessStack, nil
9✔
1720
}
1721

1722
// TaprootHtlcSpendSuccess spends a second-level HTLC output via the redemption
1723
// path. This should be used to sweep funds after the pre-image is known.
1724
//
1725
// NOTE: The caller MUST set the txn version, sequence number, and sign
1726
// descriptor's sig hash cache before invocation.
1727
func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
1728
        sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey,
1729
        tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
18✔
1730

18✔
1731
        // First, we'll generate the sweep signature based on the populated
18✔
1732
        // sign desc. This should give us a valid schnorr signature for the
18✔
1733
        // sole script path leaf.
18✔
1734
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
18✔
1735
        if err != nil {
18✔
1736
                return nil, err
×
1737
        }
×
1738

1739
        var ctrlBlock []byte
18✔
1740
        if signDesc.ControlBlock == nil {
29✔
1741
                // Now that we have the sweep signature, we'll construct the
11✔
1742
                // control block needed to spend the script path.
11✔
1743
                redeemControlBlock := MakeTaprootCtrlBlock(
11✔
1744
                        signDesc.WitnessScript, revokeKey, tapscriptTree,
11✔
1745
                )
11✔
1746

11✔
1747
                ctrlBlock, err = redeemControlBlock.ToBytes()
11✔
1748
                if err != nil {
11✔
1749
                        return nil, err
×
1750
                }
×
1751
        } else {
7✔
1752
                ctrlBlock = signDesc.ControlBlock
7✔
1753
        }
7✔
1754

1755
        // Now that we have the redeem control block, we can construct the
1756
        // final witness needed to spend the script:
1757
        //
1758
        //  <success sig> <success script> <control_block>
1759
        witnessStack := make(wire.TxWitness, 3)
18✔
1760
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
18✔
1761
        witnessStack[1] = signDesc.WitnessScript
18✔
1762
        witnessStack[2] = ctrlBlock
18✔
1763

18✔
1764
        return witnessStack, nil
18✔
1765
}
1766

1767
// LeaseSecondLevelHtlcScript is the uniform script that's used as the output
1768
// for the second-level HTLC transactions. The second level transaction acts as
1769
// a sort of covenant, ensuring that a 2-of-2 multi-sig output can only be
1770
// spent in a particular way, and to a particular output.
1771
//
1772
// Possible Input Scripts:
1773
//
1774
//   - To revoke an HTLC output that has been transitioned to the claim+delay
1775
//     state:
1776
//     <revoke sig> 1
1777
//
1778
//   - To claim an HTLC output, either with a pre-image or due to a timeout:
1779
//     <delay sig> 0
1780
//
1781
// Output Script:
1782
//
1783
//         OP_IF
1784
//                <revoke key>
1785
//         OP_ELSE
1786
//                <lease maturity in blocks>
1787
//                OP_CHECKLOCKTIMEVERIFY
1788
//                OP_DROP
1789
//                <delay in blocks>
1790
//                OP_CHECKSEQUENCEVERIFY
1791
//                OP_DROP
1792
//                <delay key>
1793
//         OP_ENDIF
1794
//         OP_CHECKSIG.
1795
func LeaseSecondLevelHtlcScript(revocationKey, delayKey *btcec.PublicKey,
1796
        csvDelay, cltvExpiry uint32) ([]byte, error) {
5✔
1797

5✔
1798
        // Build a script template with conditional paths for revocation and normal spending
5✔
1799
        // If this is the revocation clause, the spender will push a 1, forcing the first path
5✔
1800
        // Otherwise, this is either the sender or receiver of the HTLC attempting to claim
5✔
1801
        return txscript.ScriptTemplate(
5✔
1802
                `
5✔
1803
                OP_IF
5✔
1804
                        {{ hex .RevokeKey }}
5✔
1805
                OP_ELSE
5✔
1806
                        {{ .CltvExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
5✔
1807
                        {{ .CsvDelay }} OP_CHECKSEQUENCEVERIFY OP_DROP
5✔
1808
                        {{ hex .DelayKey }}
5✔
1809
                OP_ENDIF OP_CHECKSIG`,
5✔
1810
                txscript.WithScriptTemplateParams(TemplateParams{
5✔
1811
                        "RevokeKey":  revocationKey.SerializeCompressed(),
5✔
1812
                        "CltvExpiry": int64(cltvExpiry),
5✔
1813
                        "CsvDelay":   int64(csvDelay),
5✔
1814
                        "DelayKey":   delayKey.SerializeCompressed(),
5✔
1815
                }),
5✔
1816
        )
5✔
1817
}
5✔
1818

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

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

11✔
1830
        // Finally, OP_CSV requires that the version of the transaction
11✔
1831
        // spending a pkscript with OP_CSV within it *must* be >= 2.
11✔
1832
        sweepTx.Version = 2
11✔
1833

11✔
1834
        // As we mutated the transaction, we'll re-calculate the sighashes for
11✔
1835
        // this instance.
11✔
1836
        signDesc.SigHashes = NewTxSigHashesV0Only(sweepTx)
11✔
1837

11✔
1838
        // With the proper sequence and version set, we'll now sign the timeout
11✔
1839
        // transaction using the passed signed descriptor. In order to generate
11✔
1840
        // a valid signature, then signDesc should be using the base delay
11✔
1841
        // public key, and the proper single tweak bytes.
11✔
1842
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
11✔
1843
        if err != nil {
11✔
1844
                return nil, err
×
1845
        }
×
1846

1847
        // We set a zero as the first element the witness stack (ignoring the
1848
        // witness script), in order to force execution to the second portion
1849
        // of the if clause.
1850
        witnessStack := wire.TxWitness(make([][]byte, 3))
11✔
1851
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
11✔
1852
        witnessStack[1] = nil
11✔
1853
        witnessStack[2] = signDesc.WitnessScript
11✔
1854

11✔
1855
        return witnessStack, nil
11✔
1856
}
1857

1858
// HtlcSpendRevoke spends a second-level HTLC output. This function is to be
1859
// used by the sender or receiver of an HTLC to claim the HTLC after a revoked
1860
// commitment transaction was broadcast.
1861
func HtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
1862
        revokeTx *wire.MsgTx) (wire.TxWitness, error) {
14✔
1863

14✔
1864
        // We don't need any spacial modifications to the transaction as this
14✔
1865
        // is just sweeping a revoked HTLC output. So we'll generate a regular
14✔
1866
        // witness signature.
14✔
1867
        sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
14✔
1868
        if err != nil {
14✔
1869
                return nil, err
×
1870
        }
×
1871

1872
        // We set a one as the first element the witness stack (ignoring the
1873
        // witness script), in order to force execution to the revocation
1874
        // clause in the second level HTLC script.
1875
        witnessStack := wire.TxWitness(make([][]byte, 3))
14✔
1876
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
14✔
1877
        witnessStack[1] = []byte{1}
14✔
1878
        witnessStack[2] = signDesc.WitnessScript
14✔
1879

14✔
1880
        return witnessStack, nil
14✔
1881
}
1882

1883
// HtlcSecondLevelSpend exposes the public witness generation function for
1884
// spending an HTLC success transaction, either due to an expiring time lock or
1885
// having had the payment preimage. This method is able to spend any
1886
// second-level HTLC transaction, assuming the caller sets the locktime or
1887
// seqno properly.
1888
//
1889
// NOTE: The caller MUST set the txn version, sequence number, and sign
1890
// descriptor's sig hash cache before invocation.
1891
func HtlcSecondLevelSpend(signer Signer, signDesc *SignDescriptor,
1892
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
3✔
1893

3✔
1894
        // With the proper sequence and version set, we'll now sign the timeout
3✔
1895
        // transaction using the passed signed descriptor. In order to generate
3✔
1896
        // a valid signature, then signDesc should be using the base delay
3✔
1897
        // public key, and the proper single tweak bytes.
3✔
1898
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1899
        if err != nil {
3✔
1900
                return nil, err
×
1901
        }
×
1902

1903
        // We set a zero as the first element the witness stack (ignoring the
1904
        // witness script), in order to force execution to the second portion
1905
        // of the if clause.
1906
        witnessStack := wire.TxWitness(make([][]byte, 3))
3✔
1907
        witnessStack[0] = append(sweepSig.Serialize(), byte(txscript.SigHashAll))
3✔
1908
        witnessStack[1] = nil
3✔
1909
        witnessStack[2] = signDesc.WitnessScript
3✔
1910

3✔
1911
        return witnessStack, nil
3✔
1912
}
1913

1914
// LockTimeToSequence converts the passed relative locktime to a sequence
1915
// number in accordance to BIP-68.
1916
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
1917
//   - (Compatibility)
1918
func LockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
28✔
1919
        if !isSeconds {
56✔
1920
                // The locktime is to be expressed in confirmations.
28✔
1921
                return locktime
28✔
1922
        }
28✔
1923

1924
        // Set the 22nd bit which indicates the lock time is in seconds, then
1925
        // shift the locktime over by 9 since the time granularity is in
1926
        // 512-second intervals (2^9). This results in a max lock-time of
1927
        // 33,554,431 seconds, or 1.06 years.
1928
        return SequenceLockTimeSeconds | (locktime >> 9)
×
1929
}
1930

1931
// CommitScriptToSelf constructs the public key script for the output on the
1932
// commitment transaction paying to the "owner" of said commitment transaction.
1933
// If the other party learns of the preimage to the revocation hash, then they
1934
// can claim all the settled funds in the channel, plus the unsettled funds.
1935
//
1936
// Possible Input Scripts:
1937
//
1938
//        REVOKE:     <sig> 1
1939
//        SENDRSWEEP: <sig> <emptyvector>
1940
//
1941
// Output Script:
1942
//
1943
//        OP_IF
1944
//            <revokeKey>
1945
//        OP_ELSE
1946
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
1947
//            <selfKey>
1948
//        OP_ENDIF
1949
//        OP_CHECKSIG
1950
func CommitScriptToSelf(csvTimeout uint32, selfKey, revokeKey *btcec.PublicKey) ([]byte, error) {
9,503✔
1951
        // This script is spendable under two conditions: either the
9,503✔
1952
        // 'csvTimeout' has passed and we can redeem our funds, or they can
9,503✔
1953
        // produce a valid signature with the revocation public key. The
9,503✔
1954
        // revocation public key will *only* be known to the other party if we
9,503✔
1955
        // have divulged the revocation hash, allowing them to homomorphically
9,503✔
1956
        // derive the proper private key which corresponds to the revoke public
9,503✔
1957
        // key.
9,503✔
1958
        return txscript.ScriptTemplate(
9,503✔
1959
                `
9,503✔
1960
                OP_IF
9,503✔
1961
                        {{ hex .RevokeKey }}
9,503✔
1962
                OP_ELSE
9,503✔
1963
                        {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP
9,503✔
1964
                        {{ hex .SelfKey }}
9,503✔
1965
                OP_ENDIF
9,503✔
1966
                OP_CHECKSIG`,
9,503✔
1967
                txscript.WithScriptTemplateParams(TemplateParams{
9,503✔
1968
                        "RevokeKey":  revokeKey.SerializeCompressed(),
9,503✔
1969
                        "CsvTimeout": int64(csvTimeout),
9,503✔
1970
                        "SelfKey":    selfKey.SerializeCompressed(),
9,503✔
1971
                }),
9,503✔
1972
        )
9,503✔
1973
}
9,503✔
1974

1975
// CommitScriptTree holds the taproot output key (in this case the revocation
1976
// key, or a NUMs point for the remote output) along with the tapscript leaf
1977
// that can spend the output after a delay.
1978
type CommitScriptTree struct {
1979
        ScriptTree
1980

1981
        // SettleLeaf is the leaf used to settle the output after the delay.
1982
        SettleLeaf txscript.TapLeaf
1983

1984
        // RevocationLeaf is the leaf used to spend the output with the
1985
        // revocation key signature.
1986
        RevocationLeaf txscript.TapLeaf
1987

1988
        // AuxLeaf is an auxiliary leaf that can be used to extend the base
1989
        // commitment script tree with new spend paths, or just as extra
1990
        // commitment space. When present, this leaf will always be in the
1991
        // left-most or right-most area of the tapscript tree.
1992
        AuxLeaf AuxTapLeaf
1993
}
1994

1995
// A compile time check to ensure CommitScriptTree implements the
1996
// TapscriptDescriptor interface.
1997
var _ TapscriptDescriptor = (*CommitScriptTree)(nil)
1998

1999
// WitnessScriptToSign returns the witness script that we'll use when signing
2000
// for the remote party, and also verifying signatures on our transactions. As
2001
// an example, when we create an outgoing HTLC for the remote party, we want to
2002
// sign their success path.
2003
func (c *CommitScriptTree) WitnessScriptToSign() []byte {
×
2004
        // TODO(roasbeef): abstraction leak here? always dependent
×
2005
        return nil
×
2006
}
×
2007

2008
// WitnessScriptForPath returns the witness script for the given spending path.
2009
// An error is returned if the path is unknown.
2010
func (c *CommitScriptTree) WitnessScriptForPath(
2011
        path ScriptPath) ([]byte, error) {
7✔
2012

7✔
2013
        switch path {
7✔
2014
        // For the commitment output, the delay and success path are the same,
2015
        // so we'll fall through here to success.
2016
        case ScriptPathDelay:
7✔
2017
                fallthrough
7✔
2018
        case ScriptPathSuccess:
7✔
2019
                return c.SettleLeaf.Script, nil
7✔
2020
        case ScriptPathRevocation:
3✔
2021
                return c.RevocationLeaf.Script, nil
3✔
2022
        default:
×
2023
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2024
        }
2025
}
2026

2027
// CtrlBlockForPath returns the control block for the given spending path. For
2028
// script types that don't have a control block, nil is returned.
2029
func (c *CommitScriptTree) CtrlBlockForPath(
2030
        path ScriptPath) (*txscript.ControlBlock, error) {
7✔
2031

7✔
2032
        switch path {
7✔
2033
        case ScriptPathDelay:
7✔
2034
                fallthrough
7✔
2035
        case ScriptPathSuccess:
7✔
2036
                return lnutils.Ptr(MakeTaprootCtrlBlock(
7✔
2037
                        c.SettleLeaf.Script, c.InternalKey,
7✔
2038
                        c.TapscriptTree,
7✔
2039
                )), nil
7✔
2040
        case ScriptPathRevocation:
3✔
2041
                return lnutils.Ptr(MakeTaprootCtrlBlock(
3✔
2042
                        c.RevocationLeaf.Script, c.InternalKey,
3✔
2043
                        c.TapscriptTree,
3✔
2044
                )), nil
3✔
2045
        default:
×
2046
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2047
        }
2048
}
2049

2050
// Tree returns the underlying ScriptTree of the CommitScriptTree.
2051
func (c *CommitScriptTree) Tree() ScriptTree {
×
2052
        return c.ScriptTree
×
2053
}
×
2054

2055
// taprootScriptOpts is a set of options that modify the behavior of the way we
2056
// create taproot scripts.
2057
type taprootScriptOpts struct {
2058
        prodScript bool
2059
}
2060

2061
// TaprootScriptOpt is a functional option that allows us to modify the behavior
2062
// of the taproot script creation.
2063
type TaprootScriptOpt func(*taprootScriptOpts)
2064

2065
// defaultTaprootScriptOpt is the default set of options that we use when
2066
// creating taproot scripts.
2067
func defaultTaprootScriptOpt() *taprootScriptOpts {
2,685✔
2068
        return &taprootScriptOpts{
2,685✔
2069
                prodScript: false,
2,685✔
2070
        }
2,685✔
2071
}
2,685✔
2072

2073
// WithProdScripts is a functional option that allows us to create scripts to
2074
// match the final version of the taproot channels.
NEW
2075
func WithProdScripts() func(*taprootScriptOpts) {
×
NEW
2076
        return func(o *taprootScriptOpts) {
×
NEW
2077
                o.prodScript = true
×
NEW
2078
        }
×
2079
}
2080

2081
// NewLocalCommitScriptTree returns a new CommitScript tree that can be used to
2082
// create and spend the commitment output for the local party.
2083
func NewLocalCommitScriptTree(csvTimeout uint32, selfKey,
2084
        revokeKey *btcec.PublicKey, auxLeaf AuxTapLeaf,
2085
        opts ...TaprootScriptOpt) (*CommitScriptTree, error) {
1,506✔
2086

1,506✔
2087
        // First, we'll need to construct the tapLeaf that'll be our delay CSV
1,506✔
2088
        // clause.
1,506✔
2089
        delayScript, err := TaprootLocalCommitDelayScript(
1,506✔
2090
                csvTimeout, selfKey, opts...,
1,506✔
2091
        )
1,506✔
2092
        if err != nil {
1,506✔
2093
                return nil, err
×
2094
        }
×
2095

2096
        // Next, we'll need to construct the revocation path, which is just a
2097
        // simple checksig script.
2098
        revokeScript, err := TaprootLocalCommitRevokeScript(
1,506✔
2099
                selfKey, revokeKey, opts...,
1,506✔
2100
        )
1,506✔
2101
        if err != nil {
1,506✔
2102
                return nil, err
×
2103
        }
×
2104

2105
        // With both scripts computed, we'll now create a tapscript tree with
2106
        // the two leaves, and then obtain a root from that.
2107
        delayTapLeaf := txscript.NewBaseTapLeaf(delayScript)
1,506✔
2108
        revokeTapLeaf := txscript.NewBaseTapLeaf(revokeScript)
1,506✔
2109

1,506✔
2110
        tapLeaves := []txscript.TapLeaf{delayTapLeaf, revokeTapLeaf}
1,506✔
2111
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
1,507✔
2112
                tapLeaves = append(tapLeaves, l)
1✔
2113
        })
1✔
2114

2115
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
1,506✔
2116
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
1,506✔
2117

1,506✔
2118
        // Now that we have our root, we can arrive at the final output script
1,506✔
2119
        // by tweaking the internal key with this root.
1,506✔
2120
        toLocalOutputKey := txscript.ComputeTaprootOutputKey(
1,506✔
2121
                &TaprootNUMSKey, tapScriptRoot[:],
1,506✔
2122
        )
1,506✔
2123

1,506✔
2124
        return &CommitScriptTree{
1,506✔
2125
                ScriptTree: ScriptTree{
1,506✔
2126
                        TaprootKey:    toLocalOutputKey,
1,506✔
2127
                        TapscriptTree: tapScriptTree,
1,506✔
2128
                        TapscriptRoot: tapScriptRoot[:],
1,506✔
2129
                        InternalKey:   &TaprootNUMSKey,
1,506✔
2130
                },
1,506✔
2131
                SettleLeaf:     delayTapLeaf,
1,506✔
2132
                RevocationLeaf: revokeTapLeaf,
1,506✔
2133
                AuxLeaf:        auxLeaf,
1,506✔
2134
        }, nil
1,506✔
2135
}
2136

2137
// TaprootLocalCommitDelayScript builds the tap leaf with the CSV delay script
2138
// for the to-local output.
2139
func TaprootLocalCommitDelayScript(csvTimeout uint32,
2140
        selfKey *btcec.PublicKey, opts ...TaprootScriptOpt) ([]byte, error) {
1,506✔
2141

1,506✔
2142
        opt := defaultTaprootScriptOpt()
1,506✔
2143
        for _, o := range opts {
1,506✔
NEW
2144
                o(opt)
×
NEW
2145
        }
×
2146

2147
        var scriptTemplate string
1,506✔
2148
        switch {
1,506✔
2149
        case !opt.prodScript:
1,506✔
2150
                scriptTemplate = `
1,506✔
2151
                {{ hex .SelfKey }} OP_CHECKSIG 
1,506✔
2152
                {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP`
1,506✔
2153

NEW
2154
        default:
×
NEW
2155
                scriptTemplate = `
×
NEW
2156
                {{ hex .SelfKey }} OP_CHECKSIGVERIFY
×
NEW
2157
                {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY`
×
2158
        }
2159

2160
        return txscript.ScriptTemplate(
1,506✔
2161
                scriptTemplate,
1,506✔
2162
                txscript.WithScriptTemplateParams(TemplateParams{
1,506✔
2163
                        "SelfKey":    schnorr.SerializePubKey(selfKey),
1,506✔
2164
                        "CsvTimeout": int64(csvTimeout),
1,506✔
2165
                }),
1,506✔
2166
        )
1,506✔
2167
}
2168

2169
// TaprootLocalCommitRevokeScript builds the tap leaf with the revocation path
2170
// for the to-local output.
2171
func TaprootLocalCommitRevokeScript(selfKey, revokeKey *btcec.PublicKey,
2172
        opts ...TaprootScriptOpt) ([]byte, error) {
1,508✔
2173

1,508✔
2174
        return txscript.ScriptTemplate(
1,508✔
2175
                `
1,508✔
2176
                {{ hex .SelfKey }} OP_DROP 
1,508✔
2177
                {{ hex .RevokeKey }} OP_CHECKSIG`,
1,508✔
2178
                txscript.WithScriptTemplateParams(TemplateParams{
1,508✔
2179
                        "SelfKey":   schnorr.SerializePubKey(selfKey),
1,508✔
2180
                        "RevokeKey": schnorr.SerializePubKey(revokeKey),
1,508✔
2181
                }),
1,508✔
2182
        )
1,508✔
2183
}
1,508✔
2184

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

×
2221
        commitScriptTree, err := NewLocalCommitScriptTree(
×
2222
                csvTimeout, selfKey, revokeKey, NoneTapLeaf(),
×
2223
        )
×
2224
        if err != nil {
×
2225
                return nil, err
×
2226
        }
×
2227

2228
        return commitScriptTree.TaprootKey, nil
×
2229
}
2230

2231
// MakeTaprootCtrlBlock takes a leaf script, the internal key (usually the
2232
// revoke key), and a script tree and creates a valid control block for a spend
2233
// of the leaf.
2234
func MakeTaprootCtrlBlock(leafScript []byte, internalKey *btcec.PublicKey,
2235
        scriptTree *txscript.IndexedTapScriptTree) txscript.ControlBlock {
119✔
2236

119✔
2237
        tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
119✔
2238
        scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
119✔
2239
        settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
119✔
2240

119✔
2241
        return settleMerkleProof.ToControlBlock(internalKey)
119✔
2242
}
119✔
2243

2244
// TaprootCommitSpendSuccess constructs a valid witness allowing a node to
2245
// sweep the settled taproot output after the delay has passed for a force
2246
// close.
2247
func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
2248
        sweepTx *wire.MsgTx,
2249
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
14✔
2250

14✔
2251
        // First, we'll need to construct a valid control block to execute the
14✔
2252
        // leaf script for sweep settlement.
14✔
2253
        //
14✔
2254
        // TODO(roasbeef); make into closure instead? only need reovke key and
14✔
2255
        // scriptTree to make the ctrl block -- then default version that would
14✔
2256
        // take froms ign desc?
14✔
2257
        var ctrlBlockBytes []byte
14✔
2258
        if signDesc.ControlBlock == nil {
25✔
2259
                settleControlBlock := MakeTaprootCtrlBlock(
11✔
2260
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
11✔
2261
                )
11✔
2262
                ctrlBytes, err := settleControlBlock.ToBytes()
11✔
2263
                if err != nil {
11✔
2264
                        return nil, err
×
2265
                }
×
2266

2267
                ctrlBlockBytes = ctrlBytes
11✔
2268
        } else {
3✔
2269
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2270
        }
3✔
2271

2272
        // With the control block created, we'll now generate the signature we
2273
        // need to authorize the spend.
2274
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
14✔
2275
        if err != nil {
14✔
2276
                return nil, err
×
2277
        }
×
2278

2279
        // The final witness stack will be:
2280
        //
2281
        //  <sweep sig> <sweep script> <control block>
2282
        witnessStack := make(wire.TxWitness, 3)
14✔
2283
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
14✔
2284
        witnessStack[1] = signDesc.WitnessScript
14✔
2285
        witnessStack[2] = ctrlBlockBytes
14✔
2286

14✔
2287
        return witnessStack, nil
14✔
2288
}
2289

2290
// TaprootCommitSpendRevoke constructs a valid witness allowing a node to sweep
2291
// the revoked taproot output of a malicious peer.
2292
func TaprootCommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2293
        revokeTx *wire.MsgTx,
2294
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
696✔
2295

696✔
2296
        // First, we'll need to construct a valid control block to execute the
696✔
2297
        // leaf script for revocation path.
696✔
2298
        var ctrlBlockBytes []byte
696✔
2299
        if signDesc.ControlBlock == nil {
705✔
2300
                revokeCtrlBlock := MakeTaprootCtrlBlock(
9✔
2301
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
9✔
2302
                )
9✔
2303
                revokeBytes, err := revokeCtrlBlock.ToBytes()
9✔
2304
                if err != nil {
9✔
2305
                        return nil, err
×
2306
                }
×
2307

2308
                ctrlBlockBytes = revokeBytes
9✔
2309
        } else {
687✔
2310
                ctrlBlockBytes = signDesc.ControlBlock
687✔
2311
        }
687✔
2312

2313
        // With the control block created, we'll now generate the signature we
2314
        // need to authorize the spend.
2315
        revokeSig, err := signer.SignOutputRaw(revokeTx, signDesc)
696✔
2316
        if err != nil {
696✔
2317
                return nil, err
×
2318
        }
×
2319

2320
        // The final witness stack will be:
2321
        //
2322
        //  <revoke sig sig> <revoke script> <control block>
2323
        witnessStack := make(wire.TxWitness, 3)
696✔
2324
        witnessStack[0] = maybeAppendSighash(revokeSig, signDesc.HashType)
696✔
2325
        witnessStack[1] = signDesc.WitnessScript
696✔
2326
        witnessStack[2] = ctrlBlockBytes
696✔
2327

696✔
2328
        return witnessStack, nil
696✔
2329
}
2330

2331
// LeaseCommitScriptToSelf constructs the public key script for the output on the
2332
// commitment transaction paying to the "owner" of said commitment transaction.
2333
// If the other party learns of the preimage to the revocation hash, then they
2334
// can claim all the settled funds in the channel, plus the unsettled funds.
2335
//
2336
// Possible Input Scripts:
2337
//
2338
//        REVOKE:     <sig> 1
2339
//        SENDRSWEEP: <sig> <emptyvector>
2340
//
2341
// Output Script:
2342
//
2343
//        OP_IF
2344
//            <revokeKey>
2345
//        OP_ELSE
2346
//            <absoluteLeaseExpiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
2347
//            <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY OP_DROP
2348
//            <selfKey>
2349
//        OP_ENDIF
2350
//        OP_CHECKSIG
2351
func LeaseCommitScriptToSelf(selfKey, revokeKey *btcec.PublicKey,
2352
        csvTimeout, leaseExpiry uint32) ([]byte, error) {
5✔
2353

5✔
2354
        // This script is spendable under two conditions: either the
5✔
2355
        // 'csvTimeout' has passed and we can redeem our funds, or they can
5✔
2356
        // produce a valid signature with the revocation public key. The
5✔
2357
        // revocation public key will *only* be known to the other party if we
5✔
2358
        // have divulged the revocation hash, allowing them to homomorphically
5✔
2359
        // derive the proper private key which corresponds to the revoke public
5✔
2360
        // key.
5✔
2361
        return txscript.ScriptTemplate(
5✔
2362
                `
5✔
2363
                OP_IF
5✔
2364
                        {{ hex .RevokeKey }}
5✔
2365
                OP_ELSE
5✔
2366
                        {{ .LeaseExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP
5✔
2367
                        {{ .CsvTimeout }} OP_CHECKSEQUENCEVERIFY OP_DROP
5✔
2368
                        {{ hex .SelfKey }}
5✔
2369
                OP_ENDIF
5✔
2370
                OP_CHECKSIG`,
5✔
2371
                txscript.WithScriptTemplateParams(TemplateParams{
5✔
2372
                        "RevokeKey":   revokeKey.SerializeCompressed(),
5✔
2373
                        "LeaseExpiry": int64(leaseExpiry),
5✔
2374
                        "CsvTimeout":  int64(csvTimeout),
5✔
2375
                        "SelfKey":     selfKey.SerializeCompressed(),
5✔
2376
                }),
5✔
2377
        )
5✔
2378
}
5✔
2379

2380
// CommitSpendTimeout constructs a valid witness allowing the owner of a
2381
// particular commitment transaction to spend the output returning settled
2382
// funds back to themselves after a relative block timeout.  In order to
2383
// properly spend the transaction, the target input's sequence number should be
2384
// set accordingly based off of the target relative block timeout within the
2385
// redeem script.  Additionally, OP_CSV requires that the version of the
2386
// transaction spending a pkscript with OP_CSV within it *must* be >= 2.
2387
func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
2388
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
9✔
2389

9✔
2390
        // Ensure the transaction version supports the validation of sequence
9✔
2391
        // locks and CSV semantics.
9✔
2392
        if sweepTx.Version < 2 {
9✔
2393
                return nil, fmt.Errorf("version of passed transaction MUST "+
×
2394
                        "be >= 2, not %v", sweepTx.Version)
×
2395
        }
×
2396

2397
        // With the sequence number in place, we're now able to properly sign
2398
        // off on the sweep transaction.
2399
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
9✔
2400
        if err != nil {
9✔
2401
                return nil, err
×
2402
        }
×
2403

2404
        // Place an empty byte as the first item in the evaluated witness stack
2405
        // to force script execution to the timeout spend clause. We need to
2406
        // place an empty byte in order to ensure our script is still valid
2407
        // from the PoV of nodes that are enforcing minimal OP_IF/OP_NOTIF.
2408
        witnessStack := wire.TxWitness(make([][]byte, 3))
9✔
2409
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
9✔
2410
        witnessStack[1] = nil
9✔
2411
        witnessStack[2] = signDesc.WitnessScript
9✔
2412

9✔
2413
        return witnessStack, nil
9✔
2414
}
2415

2416
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
2417
// settled output of a malicious counterparty who broadcasts a revoked
2418
// commitment transaction.
2419
//
2420
// NOTE: The passed SignDescriptor should include the raw (untweaked)
2421
// revocation base public key of the receiver and also the proper double tweak
2422
// value based on the commitment secret of the revoked commitment.
2423
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
2424
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
38✔
2425

38✔
2426
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
38✔
2427
        if err != nil {
38✔
2428
                return nil, err
×
2429
        }
×
2430

2431
        // Place a 1 as the first item in the evaluated witness stack to
2432
        // force script execution to the revocation clause.
2433
        witnessStack := wire.TxWitness(make([][]byte, 3))
38✔
2434
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
38✔
2435
        witnessStack[1] = []byte{1}
38✔
2436
        witnessStack[2] = signDesc.WitnessScript
38✔
2437

38✔
2438
        return witnessStack, nil
38✔
2439
}
2440

2441
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
2442
// settled no-delay output on the counterparty's commitment transaction. If the
2443
// tweakless field is true, then we'll omit the set where we tweak the pubkey
2444
// with a random set of bytes, and use it directly in the witness stack.
2445
//
2446
// NOTE: The passed SignDescriptor should include the raw (untweaked) public
2447
// key of the receiver and also the proper single tweak value based on the
2448
// current commitment point.
2449
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
2450
        sweepTx *wire.MsgTx, tweakless bool) (wire.TxWitness, error) {
32✔
2451

32✔
2452
        if signDesc.KeyDesc.PubKey == nil {
32✔
2453
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2454
                        "KeyDesc pubkey")
×
2455
        }
×
2456

2457
        // This is just a regular p2wkh spend which looks something like:
2458
        //  * witness: <sig> <pubkey>
2459
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
32✔
2460
        if err != nil {
32✔
2461
                return nil, err
×
2462
        }
×
2463

2464
        // Finally, we'll manually craft the witness. The witness here is the
2465
        // exact same as a regular p2wkh witness, depending on the value of the
2466
        // tweakless bool.
2467
        witness := make([][]byte, 2)
32✔
2468
        witness[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
32✔
2469

32✔
2470
        switch tweakless {
32✔
2471
        // If we're tweaking the key, then we use the tweaked public key as the
2472
        // last item in the witness stack which was originally used to created
2473
        // the pkScript we're spending.
2474
        case false:
11✔
2475
                witness[1] = TweakPubKeyWithTweak(
11✔
2476
                        signDesc.KeyDesc.PubKey, signDesc.SingleTweak,
11✔
2477
                ).SerializeCompressed()
11✔
2478

2479
        // Otherwise, we can just use the raw pubkey, since there's no random
2480
        // value to be combined.
2481
        case true:
24✔
2482
                witness[1] = signDesc.KeyDesc.PubKey.SerializeCompressed()
24✔
2483
        }
2484

2485
        return witness, nil
32✔
2486
}
2487

2488
// CommitScriptUnencumbered constructs the public key script on the commitment
2489
// transaction paying to the "other" party. The constructed output is a normal
2490
// p2wkh output spendable immediately, requiring no contestation period.
2491
func CommitScriptUnencumbered(key *btcec.PublicKey) ([]byte, error) {
9,162✔
2492
        // This script goes to the "other" party, and is spendable immediately.
9,162✔
2493
        return txscript.ScriptTemplate(
9,162✔
2494
                `OP_0 {{ hex .PKHash }}`,
9,162✔
2495
                txscript.WithScriptTemplateParams(TemplateParams{
9,162✔
2496
                        "PKHash": btcutil.Hash160(key.SerializeCompressed()),
9,162✔
2497
                }),
9,162✔
2498
        )
9,162✔
2499
}
9,162✔
2500

2501
// CommitScriptToRemoteConfirmed constructs the script for the output on the
2502
// commitment transaction paying to the remote party of said commitment
2503
// transaction. The money can only be spend after one confirmation.
2504
//
2505
// Possible Input Scripts:
2506
//
2507
//        SWEEP: <sig>
2508
//
2509
// Output Script:
2510
//
2511
//        <key> OP_CHECKSIGVERIFY
2512
//        1 OP_CHECKSEQUENCEVERIFY
2513
func CommitScriptToRemoteConfirmed(key *btcec.PublicKey) ([]byte, error) {
292✔
2514
        // Only the given key can spend the output after one confirmation.
292✔
2515
        return txscript.ScriptTemplate(
292✔
2516
                `
292✔
2517
                {{ hex .Key }} OP_CHECKSIGVERIFY 
292✔
2518
                OP_1 OP_CHECKSEQUENCEVERIFY`,
292✔
2519
                txscript.WithScriptTemplateParams(TemplateParams{
292✔
2520
                        "Key": key.SerializeCompressed(),
292✔
2521
                }),
292✔
2522
        )
292✔
2523
}
292✔
2524

2525
// NewRemoteCommitScriptTree constructs a new script tree for the remote party
2526
// to sweep their funds after a hard coded 1 block delay.
2527
func NewRemoteCommitScriptTree(remoteKey *btcec.PublicKey,
2528
        auxLeaf AuxTapLeaf,
2529
        opts ...TaprootScriptOpt) (*CommitScriptTree, error) {
808✔
2530

808✔
2531
        opt := defaultTaprootScriptOpt()
808✔
2532
        for _, o := range opts {
808✔
NEW
2533
                o(opt)
×
NEW
2534
        }
×
2535

2536
        var scriptTemplate string
808✔
2537
        switch {
808✔
2538
        case !opt.prodScript:
808✔
2539
                scriptTemplate = `
808✔
2540
                {{ hex .RemoteKey }} OP_CHECKSIG 
808✔
2541
                OP_1 OP_CHECKSEQUENCEVERIFY OP_DROP`
808✔
NEW
2542
        default:
×
NEW
2543
                scriptTemplate = `
×
NEW
2544
                {{ hex .RemoteKey }} OP_CHECKSIGVERIFY
×
NEW
2545
                OP_1 OP_CHECKSEQUENCEVERIFY`
×
2546
        }
2547

2548
        // First, construct the remote party's tapscript they'll use to sweep
2549
        // their outputs.
2550
        remoteScript, err := txscript.ScriptTemplate(
808✔
2551
                scriptTemplate,
808✔
2552
                txscript.WithScriptTemplateParams(TemplateParams{
808✔
2553
                        "RemoteKey": schnorr.SerializePubKey(remoteKey),
808✔
2554
                }),
808✔
2555
        )
808✔
2556
        if err != nil {
808✔
2557
                return nil, err
×
2558
        }
×
2559

2560
        tapLeaf := txscript.NewBaseTapLeaf(remoteScript)
808✔
2561

808✔
2562
        tapLeaves := []txscript.TapLeaf{tapLeaf}
808✔
2563
        auxLeaf.WhenSome(func(l txscript.TapLeaf) {
809✔
2564
                tapLeaves = append(tapLeaves, l)
1✔
2565
        })
1✔
2566

2567
        // With this script constructed, we'll map that into a tapLeaf, then
2568
        // make a new tapscript root from that.
2569
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaves...)
808✔
2570
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
808✔
2571

808✔
2572
        // Now that we have our root, we can arrive at the final output script
808✔
2573
        // by tweaking the internal key with this root.
808✔
2574
        toRemoteOutputKey := txscript.ComputeTaprootOutputKey(
808✔
2575
                &TaprootNUMSKey, tapScriptRoot[:],
808✔
2576
        )
808✔
2577

808✔
2578
        return &CommitScriptTree{
808✔
2579
                ScriptTree: ScriptTree{
808✔
2580
                        TaprootKey:    toRemoteOutputKey,
808✔
2581
                        TapscriptTree: tapScriptTree,
808✔
2582
                        TapscriptRoot: tapScriptRoot[:],
808✔
2583
                        InternalKey:   &TaprootNUMSKey,
808✔
2584
                },
808✔
2585
                SettleLeaf: tapLeaf,
808✔
2586
                AuxLeaf:    auxLeaf,
808✔
2587
        }, nil
808✔
2588
}
2589

2590
// TaprootCommitScriptToRemote constructs a taproot witness program for the
2591
// output on the commitment transaction for the remote party. For the top level
2592
// key spend, we'll use a NUMs key to ensure that only the script path can be
2593
// taken. Using a set NUMs key here also means that recovery solutions can scan
2594
// the chain given knowledge of the public key for the remote party. We then
2595
// commit to a single tapscript leaf that holds the normal CSV 1 delay
2596
// script.
2597
//
2598
// Our single tapleaf will use the following script:
2599
//
2600
//        <remotepubkey> OP_CHECKSIG
2601
//        1 OP_CHECKSEQUENCEVERIFY OP_DROP
2602
func TaprootCommitScriptToRemote(remoteKey *btcec.PublicKey,
2603
        auxLeaf AuxTapLeaf) (*btcec.PublicKey, error) {
×
2604

×
2605
        commitScriptTree, err := NewRemoteCommitScriptTree(remoteKey, auxLeaf)
×
2606
        if err != nil {
×
2607
                return nil, err
×
2608
        }
×
2609

2610
        return commitScriptTree.TaprootKey, nil
×
2611
}
2612

2613
// TaprootCommitRemoteSpend allows the remote party to sweep their output into
2614
// their wallet after an enforced 1 block delay.
2615
func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
2616
        sweepTx *wire.MsgTx,
2617
        scriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
699✔
2618

699✔
2619
        // First, we'll need to construct a valid control block to execute the
699✔
2620
        // leaf script for sweep settlement.
699✔
2621
        var ctrlBlockBytes []byte
699✔
2622
        if signDesc.ControlBlock == nil {
712✔
2623
                settleControlBlock := MakeTaprootCtrlBlock(
13✔
2624
                        signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
13✔
2625
                )
13✔
2626
                ctrlBytes, err := settleControlBlock.ToBytes()
13✔
2627
                if err != nil {
13✔
2628
                        return nil, err
×
2629
                }
×
2630

2631
                ctrlBlockBytes = ctrlBytes
13✔
2632
        } else {
686✔
2633
                ctrlBlockBytes = signDesc.ControlBlock
686✔
2634
        }
686✔
2635

2636
        // With the control block created, we'll now generate the signature we
2637
        // need to authorize the spend.
2638
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
699✔
2639
        if err != nil {
699✔
2640
                return nil, err
×
2641
        }
×
2642

2643
        // The final witness stack will be:
2644
        //
2645
        //  <sweep sig> <sweep script> <control block>
2646
        witnessStack := make(wire.TxWitness, 3)
699✔
2647
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
699✔
2648
        witnessStack[1] = signDesc.WitnessScript
699✔
2649
        witnessStack[2] = ctrlBlockBytes
699✔
2650

699✔
2651
        return witnessStack, nil
699✔
2652
}
2653

2654
// LeaseCommitScriptToRemoteConfirmed constructs the script for the output on
2655
// the commitment transaction paying to the remote party of said commitment
2656
// transaction. The money can only be spend after one confirmation.
2657
//
2658
// Possible Input Scripts:
2659
//
2660
//        SWEEP: <sig>
2661
//
2662
// Output Script:
2663
//
2664
//                <key> OP_CHECKSIGVERIFY
2665
//             <lease maturity in blocks> OP_CHECKLOCKTIMEVERIFY OP_DROP
2666
//                1 OP_CHECKSEQUENCEVERIFY
2667
func LeaseCommitScriptToRemoteConfirmed(key *btcec.PublicKey,
2668
        leaseExpiry uint32) ([]byte, error) {
5✔
2669

5✔
2670
        // This script adds lease expiration constraint in addition to the
5✔
2671
        // standard remote confirmed script requirements.
5✔
2672
        return txscript.ScriptTemplate(
5✔
2673
                `
5✔
2674
                {{ hex .Key }} OP_CHECKSIGVERIFY 
5✔
2675
                {{ .LeaseExpiry }} OP_CHECKLOCKTIMEVERIFY OP_DROP 
5✔
2676
                OP_1 OP_CHECKSEQUENCEVERIFY`,
5✔
2677
                txscript.WithScriptTemplateParams(TemplateParams{
5✔
2678
                        "Key":         key.SerializeCompressed(),
5✔
2679
                        "LeaseExpiry": int64(leaseExpiry),
5✔
2680
                }),
5✔
2681
        )
5✔
2682
}
5✔
2683

2684
// CommitSpendToRemoteConfirmed constructs a valid witness allowing a node to
2685
// spend their settled output on the counterparty's commitment transaction when
2686
// it has one confirmetion. This is used for the anchor channel type. The
2687
// spending key will always be non-tweaked for this output type.
2688
func CommitSpendToRemoteConfirmed(signer Signer, signDesc *SignDescriptor,
2689
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
15✔
2690

15✔
2691
        if signDesc.KeyDesc.PubKey == nil {
15✔
2692
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2693
                        "KeyDesc pubkey")
×
2694
        }
×
2695

2696
        // Similar to non delayed output, only a signature is needed.
2697
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
15✔
2698
        if err != nil {
15✔
2699
                return nil, err
×
2700
        }
×
2701

2702
        // Finally, we'll manually craft the witness. The witness here is the
2703
        // signature and the redeem script.
2704
        witnessStack := make([][]byte, 2)
15✔
2705
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
15✔
2706
        witnessStack[1] = signDesc.WitnessScript
15✔
2707

15✔
2708
        return witnessStack, nil
15✔
2709
}
2710

2711
// CommitScriptAnchor constructs the script for the anchor output spendable by
2712
// the given key immediately, or by anyone after 16 confirmations.
2713
//
2714
// Possible Input Scripts:
2715
//
2716
//        By owner:                                <sig>
2717
//        By anyone (after 16 conf):        <emptyvector>
2718
//
2719
// Output Script:
2720
//
2721
//        <funding_pubkey> OP_CHECKSIG OP_IFDUP
2722
//        OP_NOTIF
2723
//          OP_16 OP_CSV
2724
//        OP_ENDIF
2725
func CommitScriptAnchor(key *btcec.PublicKey) ([]byte, error) {
513✔
2726
        // Build the anchor script with two possible spending paths:
513✔
2727
        // 1. Spend immediately with key (the normal path)
513✔
2728
        // 2. Spend after 16 confirmations by anyone (the alternative path)
513✔
2729
        return txscript.ScriptTemplate(
513✔
2730
                `
513✔
2731
                {{ hex .Key }} OP_CHECKSIG OP_IFDUP 
513✔
2732
                OP_NOTIF 
513✔
2733
                        OP_16 OP_CHECKSEQUENCEVERIFY 
513✔
2734
                OP_ENDIF`,
513✔
2735
                txscript.WithScriptTemplateParams(TemplateParams{
513✔
2736
                        "Key": key.SerializeCompressed(),
513✔
2737
                }),
513✔
2738
        )
513✔
2739
}
513✔
2740

2741
// AnchorScriptTree holds all the contents needed to sweep a taproot anchor
2742
// output on chain.
2743
type AnchorScriptTree struct {
2744
        ScriptTree
2745

2746
        // SweepLeaf is the leaf used to settle the output after the delay.
2747
        SweepLeaf txscript.TapLeaf
2748
}
2749

2750
// NewAnchorScriptTree makes a new script tree for an anchor output with the
2751
// passed anchor key.
2752
func NewAnchorScriptTree(
2753
        anchorKey *btcec.PublicKey) (*AnchorScriptTree, error) {
365✔
2754

365✔
2755
        // The main script used is just a OP_16 CSV (anyone can sweep after 16
365✔
2756
        // blocks).
365✔
2757
        anchorScript, err := txscript.ScriptTemplate(
365✔
2758
                `OP_16 OP_CHECKSEQUENCEVERIFY`,
365✔
2759
        )
365✔
2760
        if err != nil {
365✔
2761
                return nil, err
×
2762
        }
×
2763

2764
        // With the script, we can make our sole leaf, then derive the root
2765
        // from that.
2766
        tapLeaf := txscript.NewBaseTapLeaf(anchorScript)
365✔
2767
        tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)
365✔
2768
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
365✔
2769

365✔
2770
        // Now that we have our root, we can arrive at the final output script
365✔
2771
        // by tweaking the internal key with this root.
365✔
2772
        anchorOutputKey := txscript.ComputeTaprootOutputKey(
365✔
2773
                anchorKey, tapScriptRoot[:],
365✔
2774
        )
365✔
2775

365✔
2776
        return &AnchorScriptTree{
365✔
2777
                ScriptTree: ScriptTree{
365✔
2778
                        TaprootKey:    anchorOutputKey,
365✔
2779
                        TapscriptTree: tapScriptTree,
365✔
2780
                        TapscriptRoot: tapScriptRoot[:],
365✔
2781
                        InternalKey:   anchorKey,
365✔
2782
                },
365✔
2783
                SweepLeaf: tapLeaf,
365✔
2784
        }, nil
365✔
2785
}
2786

2787
// WitnessScriptToSign returns the witness script that we'll use when signing
2788
// for the remote party, and also verifying signatures on our transactions. As
2789
// an example, when we create an outgoing HTLC for the remote party, we want to
2790
// sign their success path.
2791
func (a *AnchorScriptTree) WitnessScriptToSign() []byte {
×
2792
        return a.SweepLeaf.Script
×
2793
}
×
2794

2795
// WitnessScriptForPath returns the witness script for the given spending path.
2796
// An error is returned if the path is unknown.
2797
func (a *AnchorScriptTree) WitnessScriptForPath(
2798
        path ScriptPath) ([]byte, error) {
11✔
2799

11✔
2800
        switch path {
11✔
2801
        case ScriptPathDelay:
×
2802
                fallthrough
×
2803
        case ScriptPathSuccess:
11✔
2804
                return a.SweepLeaf.Script, nil
11✔
2805

2806
        default:
×
2807
                return nil, fmt.Errorf("unknown script path: %v", path)
×
2808
        }
2809
}
2810

2811
// CtrlBlockForPath returns the control block for the given spending path. For
2812
// script types that don't have a control block, nil is returned.
2813
func (a *AnchorScriptTree) CtrlBlockForPath(
2814
        path ScriptPath) (*txscript.ControlBlock, error) {
×
2815

×
2816
        switch path {
×
2817
        case ScriptPathDelay:
×
2818
                fallthrough
×
2819
        case ScriptPathSuccess:
×
2820
                return lnutils.Ptr(MakeTaprootCtrlBlock(
×
2821
                        a.SweepLeaf.Script, a.InternalKey,
×
2822
                        a.TapscriptTree,
×
2823
                )), nil
×
2824

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

2830
// Tree returns the underlying ScriptTree of the AnchorScriptTree.
2831
func (a *AnchorScriptTree) Tree() ScriptTree {
×
2832
        return a.ScriptTree
×
2833
}
×
2834

2835
// A compile time check to ensure AnchorScriptTree implements the
2836
// TapscriptDescriptor interface.
2837
var _ TapscriptDescriptor = (*AnchorScriptTree)(nil)
2838

2839
// TaprootOutputKeyAnchor returns the segwit v1 (taproot) witness program that
2840
// encodes the anchor output spending conditions: the passed key can be used
2841
// for keyspend, with the OP_CSV 16 clause living within an internal tapscript
2842
// leaf.
2843
//
2844
// Spend paths:
2845
//   - Key spend: <key_signature>
2846
//   - Script spend: OP_16 CSV <control_block>
2847
func TaprootOutputKeyAnchor(key *btcec.PublicKey) (*btcec.PublicKey, error) {
×
2848
        anchorScriptTree, err := NewAnchorScriptTree(key)
×
2849
        if err != nil {
×
2850
                return nil, err
×
2851
        }
×
2852

2853
        return anchorScriptTree.TaprootKey, nil
×
2854
}
2855

2856
// TaprootAnchorSpend constructs a valid witness allowing a node to sweep their
2857
// anchor output.
2858
func TaprootAnchorSpend(signer Signer, signDesc *SignDescriptor,
2859
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
8✔
2860

8✔
2861
        // For this spend type, we only need a single signature which'll be a
8✔
2862
        // keyspend using the anchor private key.
8✔
2863
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
8✔
2864
        if err != nil {
8✔
2865
                return nil, err
×
2866
        }
×
2867

2868
        // The witness stack in this case is pretty simple: we only need to
2869
        // specify the signature generated.
2870
        witnessStack := make(wire.TxWitness, 1)
8✔
2871
        witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
8✔
2872

8✔
2873
        return witnessStack, nil
8✔
2874
}
2875

2876
// TaprootAnchorSpendAny constructs a valid witness allowing anyone to sweep
2877
// the anchor output after 16 blocks.
2878
func TaprootAnchorSpendAny(anchorKey *btcec.PublicKey) (wire.TxWitness, error) {
2✔
2879
        anchorScriptTree, err := NewAnchorScriptTree(anchorKey)
2✔
2880
        if err != nil {
2✔
2881
                return nil, err
×
2882
        }
×
2883

2884
        // For this spend, the only thing we need to do is create a valid
2885
        // control block. Other than that, there're no restrictions to how the
2886
        // output can be spent.
2887
        scriptTree := anchorScriptTree.TapscriptTree
2✔
2888
        sweepLeaf := anchorScriptTree.SweepLeaf
2✔
2889
        sweepIdx := scriptTree.LeafProofIndex[sweepLeaf.TapHash()]
2✔
2890
        sweepMerkleProof := scriptTree.LeafMerkleProofs[sweepIdx]
2✔
2891
        sweepControlBlock := sweepMerkleProof.ToControlBlock(anchorKey)
2✔
2892

2✔
2893
        // The final witness stack will be:
2✔
2894
        //
2✔
2895
        //  <sweep script> <control block>
2✔
2896
        witnessStack := make(wire.TxWitness, 2)
2✔
2897
        witnessStack[0] = sweepLeaf.Script
2✔
2898
        witnessStack[1], err = sweepControlBlock.ToBytes()
2✔
2899
        if err != nil {
2✔
2900
                return nil, err
×
2901
        }
×
2902

2903
        return witnessStack, nil
2✔
2904
}
2905

2906
// CommitSpendAnchor constructs a valid witness allowing a node to spend their
2907
// anchor output on the commitment transaction using their funding key. This is
2908
// used for the anchor channel type.
2909
func CommitSpendAnchor(signer Signer, signDesc *SignDescriptor,
2910
        sweepTx *wire.MsgTx) (wire.TxWitness, error) {
5✔
2911

5✔
2912
        if signDesc.KeyDesc.PubKey == nil {
5✔
2913
                return nil, fmt.Errorf("cannot generate witness with nil " +
×
2914
                        "KeyDesc pubkey")
×
2915
        }
×
2916

2917
        // Create a signature.
2918
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
5✔
2919
        if err != nil {
5✔
2920
                return nil, err
×
2921
        }
×
2922

2923
        // The witness here is just a signature and the redeem script.
2924
        witnessStack := make([][]byte, 2)
5✔
2925
        witnessStack[0] = append(sweepSig.Serialize(), byte(signDesc.HashType))
5✔
2926
        witnessStack[1] = signDesc.WitnessScript
5✔
2927

5✔
2928
        return witnessStack, nil
5✔
2929
}
2930

2931
// CommitSpendAnchorAnyone constructs a witness allowing anyone to spend the
2932
// anchor output after it has gotten 16 confirmations. Since no signing is
2933
// required, only knowledge of the redeem script is necessary to spend it.
2934
func CommitSpendAnchorAnyone(script []byte) (wire.TxWitness, error) {
3✔
2935
        // The witness here is just the redeem script.
3✔
2936
        witnessStack := make([][]byte, 2)
3✔
2937
        witnessStack[0] = nil
3✔
2938
        witnessStack[1] = script
3✔
2939

3✔
2940
        return witnessStack, nil
3✔
2941
}
3✔
2942

2943
// SingleTweakBytes computes set of bytes we call the single tweak. The purpose
2944
// of the single tweak is to randomize all regular delay and payment base
2945
// points. To do this, we generate a hash that binds the commitment point to
2946
// the pay/delay base point. The end result is that the basePoint is
2947
// tweaked as follows:
2948
//
2949
//   - key = basePoint + sha256(commitPoint || basePoint)*G
2950
func SingleTweakBytes(commitPoint, basePoint *btcec.PublicKey) []byte {
93,870✔
2951
        h := sha256.New()
93,870✔
2952
        h.Write(commitPoint.SerializeCompressed())
93,870✔
2953
        h.Write(basePoint.SerializeCompressed())
93,870✔
2954
        return h.Sum(nil)
93,870✔
2955
}
93,870✔
2956

2957
// TweakPubKey tweaks a public base point given a per commitment point. The per
2958
// commitment point is a unique point on our target curve for each commitment
2959
// transaction. When tweaking a local base point for use in a remote commitment
2960
// transaction, the remote party's current per commitment point is to be used.
2961
// The opposite applies for when tweaking remote keys. Precisely, the following
2962
// operation is used to "tweak" public keys:
2963
//
2964
//        tweakPub := basePoint + sha256(commitPoint || basePoint) * G
2965
//                 := G*k + sha256(commitPoint || basePoint)*G
2966
//                 := G*(k + sha256(commitPoint || basePoint))
2967
//
2968
// Therefore, if a party possess the value k, the private key of the base
2969
// point, then they are able to derive the proper private key for the
2970
// revokeKey by computing:
2971
//
2972
//        revokePriv := k + sha256(commitPoint || basePoint) mod N
2973
//
2974
// Where N is the order of the sub-group.
2975
//
2976
// The rationale for tweaking all public keys used within the commitment
2977
// contracts is to ensure that all keys are properly delinearized to avoid any
2978
// funny business when jointly collaborating to compute public and private
2979
// keys. Additionally, the use of the per commitment point ensures that each
2980
// commitment state houses a unique set of keys which is useful when creating
2981
// blinded channel outsourcing protocols.
2982
//
2983
// TODO(roasbeef): should be using double-scalar mult here
2984
func TweakPubKey(basePoint, commitPoint *btcec.PublicKey) *btcec.PublicKey {
41,120✔
2985
        tweakBytes := SingleTweakBytes(commitPoint, basePoint)
41,120✔
2986
        return TweakPubKeyWithTweak(basePoint, tweakBytes)
41,120✔
2987
}
41,120✔
2988

2989
// TweakPubKeyWithTweak is the exact same as the TweakPubKey function, however
2990
// it accepts the raw tweak bytes directly rather than the commitment point.
2991
func TweakPubKeyWithTweak(pubKey *btcec.PublicKey,
2992
        tweakBytes []byte) *btcec.PublicKey {
45,222✔
2993

45,222✔
2994
        var (
45,222✔
2995
                pubKeyJacobian btcec.JacobianPoint
45,222✔
2996
                tweakJacobian  btcec.JacobianPoint
45,222✔
2997
                resultJacobian btcec.JacobianPoint
45,222✔
2998
        )
45,222✔
2999
        tweakKey, _ := btcec.PrivKeyFromBytes(tweakBytes)
45,222✔
3000
        btcec.ScalarBaseMultNonConst(&tweakKey.Key, &tweakJacobian)
45,222✔
3001

45,222✔
3002
        pubKey.AsJacobian(&pubKeyJacobian)
45,222✔
3003
        btcec.AddNonConst(&pubKeyJacobian, &tweakJacobian, &resultJacobian)
45,222✔
3004

45,222✔
3005
        resultJacobian.ToAffine()
45,222✔
3006
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
45,222✔
3007
}
45,222✔
3008

3009
// TweakPrivKey tweaks the private key of a public base point given a per
3010
// commitment point. The per commitment secret is the revealed revocation
3011
// secret for the commitment state in question. This private key will only need
3012
// to be generated in the case that a channel counter party broadcasts a
3013
// revoked state. Precisely, the following operation is used to derive a
3014
// tweaked private key:
3015
//
3016
//   - tweakPriv := basePriv + sha256(commitment || basePub) mod N
3017
//
3018
// Where N is the order of the sub-group.
3019
func TweakPrivKey(basePriv *btcec.PrivateKey,
3020
        commitTweak []byte) *btcec.PrivateKey {
7,477✔
3021

7,477✔
3022
        // tweakInt := sha256(commitPoint || basePub)
7,477✔
3023
        tweakScalar := new(btcec.ModNScalar)
7,477✔
3024
        tweakScalar.SetByteSlice(commitTweak)
7,477✔
3025

7,477✔
3026
        tweakScalar.Add(&basePriv.Key)
7,477✔
3027

7,477✔
3028
        return &btcec.PrivateKey{Key: *tweakScalar}
7,477✔
3029
}
7,477✔
3030

3031
// DeriveRevocationPubkey derives the revocation public key given the
3032
// counterparty's commitment key, and revocation preimage derived via a
3033
// pseudo-random-function. In the event that we (for some reason) broadcast a
3034
// revoked commitment transaction, then if the other party knows the revocation
3035
// preimage, then they'll be able to derive the corresponding private key to
3036
// this private key by exploiting the homomorphism in the elliptic curve group:
3037
//   - https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
3038
//
3039
// The derivation is performed as follows:
3040
//
3041
//        revokeKey := revokeBase * sha256(revocationBase || commitPoint) +
3042
//                     commitPoint * sha256(commitPoint || revocationBase)
3043
//
3044
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint)) +
3045
//                     G*(commitSecret * sha256(commitPoint || revocationBase))
3046
//
3047
//                  := G*(revokeBasePriv * sha256(revocationBase || commitPoint) +
3048
//                        commitSecret * sha256(commitPoint || revocationBase))
3049
//
3050
// Therefore, once we divulge the revocation secret, the remote peer is able to
3051
// compute the proper private key for the revokeKey by computing:
3052
//
3053
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3054
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3055
//
3056
// Where N is the order of the sub-group.
3057
func DeriveRevocationPubkey(revokeBase,
3058
        commitPoint *btcec.PublicKey) *btcec.PublicKey {
13,180✔
3059

13,180✔
3060
        // R = revokeBase * sha256(revocationBase || commitPoint)
13,180✔
3061
        revokeTweakBytes := SingleTweakBytes(revokeBase, commitPoint)
13,180✔
3062
        revokeTweakScalar := new(btcec.ModNScalar)
13,180✔
3063
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
13,180✔
3064

13,180✔
3065
        var (
13,180✔
3066
                revokeBaseJacobian btcec.JacobianPoint
13,180✔
3067
                rJacobian          btcec.JacobianPoint
13,180✔
3068
        )
13,180✔
3069
        revokeBase.AsJacobian(&revokeBaseJacobian)
13,180✔
3070
        btcec.ScalarMultNonConst(
13,180✔
3071
                revokeTweakScalar, &revokeBaseJacobian, &rJacobian,
13,180✔
3072
        )
13,180✔
3073

13,180✔
3074
        // C = commitPoint * sha256(commitPoint || revocationBase)
13,180✔
3075
        commitTweakBytes := SingleTweakBytes(commitPoint, revokeBase)
13,180✔
3076
        commitTweakScalar := new(btcec.ModNScalar)
13,180✔
3077
        commitTweakScalar.SetByteSlice(commitTweakBytes)
13,180✔
3078

13,180✔
3079
        var (
13,180✔
3080
                commitPointJacobian btcec.JacobianPoint
13,180✔
3081
                cJacobian           btcec.JacobianPoint
13,180✔
3082
        )
13,180✔
3083
        commitPoint.AsJacobian(&commitPointJacobian)
13,180✔
3084
        btcec.ScalarMultNonConst(
13,180✔
3085
                commitTweakScalar, &commitPointJacobian, &cJacobian,
13,180✔
3086
        )
13,180✔
3087

13,180✔
3088
        // Now that we have the revocation point, we add this to their commitment
13,180✔
3089
        // public key in order to obtain the revocation public key.
13,180✔
3090
        //
13,180✔
3091
        // P = R + C
13,180✔
3092
        var resultJacobian btcec.JacobianPoint
13,180✔
3093
        btcec.AddNonConst(&rJacobian, &cJacobian, &resultJacobian)
13,180✔
3094

13,180✔
3095
        resultJacobian.ToAffine()
13,180✔
3096
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
13,180✔
3097
}
13,180✔
3098

3099
// DeriveRevocationPrivKey derives the revocation private key given a node's
3100
// commitment private key, and the preimage to a previously seen revocation
3101
// hash. Using this derived private key, a node is able to claim the output
3102
// within the commitment transaction of a node in the case that they broadcast
3103
// a previously revoked commitment transaction.
3104
//
3105
// The private key is derived as follows:
3106
//
3107
//        revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
3108
//                      (commitSecret * sha256(commitPoint || revocationBase)) mod N
3109
//
3110
// Where N is the order of the sub-group.
3111
func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
3112
        commitSecret *btcec.PrivateKey) *btcec.PrivateKey {
60✔
3113

60✔
3114
        // r = sha256(revokeBasePub || commitPoint)
60✔
3115
        revokeTweakBytes := SingleTweakBytes(
60✔
3116
                revokeBasePriv.PubKey(), commitSecret.PubKey(),
60✔
3117
        )
60✔
3118
        revokeTweakScalar := new(btcec.ModNScalar)
60✔
3119
        revokeTweakScalar.SetByteSlice(revokeTweakBytes)
60✔
3120

60✔
3121
        // c = sha256(commitPoint || revokeBasePub)
60✔
3122
        commitTweakBytes := SingleTweakBytes(
60✔
3123
                commitSecret.PubKey(), revokeBasePriv.PubKey(),
60✔
3124
        )
60✔
3125
        commitTweakScalar := new(btcec.ModNScalar)
60✔
3126
        commitTweakScalar.SetByteSlice(commitTweakBytes)
60✔
3127

60✔
3128
        // Finally to derive the revocation secret key we'll perform the
60✔
3129
        // following operation:
60✔
3130
        //
60✔
3131
        //  k = (revocationPriv * r) + (commitSecret * c) mod N
60✔
3132
        //
60✔
3133
        // This works since:
60✔
3134
        //  P = (G*a)*b + (G*c)*d
60✔
3135
        //  P = G*(a*b) + G*(c*d)
60✔
3136
        //  P = G*(a*b + c*d)
60✔
3137
        revokeHalfPriv := revokeTweakScalar.Mul(&revokeBasePriv.Key)
60✔
3138
        commitHalfPriv := commitTweakScalar.Mul(&commitSecret.Key)
60✔
3139

60✔
3140
        revocationPriv := revokeHalfPriv.Add(commitHalfPriv)
60✔
3141

60✔
3142
        return &btcec.PrivateKey{Key: *revocationPriv}
60✔
3143
}
60✔
3144

3145
// ComputeCommitmentPoint generates a commitment point given a commitment
3146
// secret. The commitment point for each state is used to randomize each key in
3147
// the key-ring and also to used as a tweak to derive new public+private keys
3148
// for the state.
3149
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
8,732✔
3150
        _, pubKey := btcec.PrivKeyFromBytes(commitSecret)
8,732✔
3151
        return pubKey
8,732✔
3152
}
8,732✔
3153

3154
// ScriptIsOpReturn returns true if the passed script is an OP_RETURN script.
3155
//
3156
// Lifted from the txscript package:
3157
// https://github.com/btcsuite/btcd/blob/cc26860b40265e1332cca8748c5dbaf3c81cc094/txscript/standard.go#L493-L526.
3158
//
3159
//nolint:ll
3160
func ScriptIsOpReturn(script []byte) bool {
13✔
3161
        // A null script is of the form:
13✔
3162
        //  OP_RETURN <optional data>
13✔
3163
        //
13✔
3164
        // Thus, it can either be a single OP_RETURN or an OP_RETURN followed by
13✔
3165
        // a data push up to MaxDataCarrierSize bytes.
13✔
3166

13✔
3167
        // The script can't possibly be a null data script if it doesn't start
13✔
3168
        // with OP_RETURN.  Fail fast to avoid more work below.
13✔
3169
        if len(script) < 1 || script[0] != txscript.OP_RETURN {
21✔
3170
                return false
8✔
3171
        }
8✔
3172

3173
        // Single OP_RETURN.
3174
        if len(script) == 1 {
9✔
3175
                return true
4✔
3176
        }
4✔
3177

3178
        // OP_RETURN followed by data push up to MaxDataCarrierSize bytes.
3179
        tokenizer := txscript.MakeScriptTokenizer(0, script[1:])
1✔
3180

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

© 2025 Coveralls, Inc