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

lightningnetwork / lnd / 10189747109

01 Aug 2024 12:31AM UTC coverage: 58.641% (+0.2%) from 58.459%
10189747109

push

github

web-flow
Merge pull request #8949 from ProofOfKeags/fn/req

[MICRO]: fn: Add new Req type to abstract the pattern of remote processing.

125217 of 213532 relevant lines covered (58.64%)

29382.04 hits per line

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

87.36
/input/script_utils.go
1
package input
2

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

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

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

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

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

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

43
        return *pub
73✔
44
}
45

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

145✔
261
        return witness
145✔
262
}
263

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

280
        return found, index
88✔
281
}
282

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

238,163✔
420
        return builder.Script()
238,163✔
421
}
422

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

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

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

5✔
448
        return witnessStack, nil
5✔
449
}
450

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

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

466
        return SenderHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
4✔
467
}
468

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

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

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

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

2✔
489
                return true, nil
2✔
490
        }
2✔
491

492
        return false, nil
2✔
493
}
494

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

643
        htlcType htlcType
644
}
645

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

33✔
795
        var hType htlcType
33✔
796
        if whoseCommit.IsLocal() {
52✔
797
                hType = htlcLocalOutgoing
19✔
798
        } else {
37✔
799
                hType = htlcRemoteIncoming
18✔
800
        }
18✔
801

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

239,519✔
1061
        return builder.Script()
239,519✔
1062
}
1063

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

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

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

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

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

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

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

18✔
1123
        return witnessStack, nil
18✔
1124
}
1125

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

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

25✔
1139
        return revokeKey, nil
25✔
1140
}
1141

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

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

1157
        return ReceiverHtlcSpendRevokeWithKey(signer, signDesc, revokeKey, sweepTx)
17✔
1158
}
1159

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

40✔
1355
        var hType htlcType
40✔
1356
        if whoseCommit.IsLocal() {
58✔
1357
                hType = htlcLocalIncoming
18✔
1358
        } else {
44✔
1359
                hType = htlcRemoteOutgoing
26✔
1360
        }
26✔
1361

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

477,351✔
1559
        return builder.Script()
477,351✔
1560
}
477,351✔
1561

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
1649
        return redemptionKey, nil
×
1650
}
1651

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5✔
1762
        return witnessStack, nil
5✔
1763
}
1764

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

11✔
1923
        return witnessStack, nil
11✔
1924
}
1925

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

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

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

14✔
1948
        return witnessStack, nil
14✔
1949
}
1950

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

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

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

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

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

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

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

13,380✔
2030
        builder.AddOp(txscript.OP_IF)
13,380✔
2031

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

13,380✔
2036
        builder.AddOp(txscript.OP_ELSE)
13,380✔
2037

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

13,380✔
2045
        builder.AddOp(txscript.OP_ENDIF)
13,380✔
2046

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

13,380✔
2051
        return builder.Script()
13,380✔
2052
}
13,380✔
2053

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1,345✔
2181
        return builder.Script()
1,345✔
2182
}
1,345✔
2183

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

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

1,347✔
2195
        return builder.Script()
1,347✔
2196
}
1,347✔
2197

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

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

2241
        return commitScriptTree.TaprootKey, nil
×
2242
}
2243

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

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

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

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

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

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

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

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

2303
        return witnessStack, nil
10✔
2304
}
2305

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

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

2324
                ctrlBlockBytes = revokeBytes
5✔
2325
        } else {
688✔
2326
                ctrlBlockBytes = signDesc.ControlBlock
688✔
2327
        }
688✔
2328

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2516
        return witness, nil
35✔
2517
}
2518

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

13,080✔
2530
        return builder.Script()
13,080✔
2531
}
13,080✔
2532

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

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

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

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

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

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

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

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

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

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

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

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

2623
        return commitScriptTree.TaprootKey, nil
×
2624
}
2625

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

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

2644
                ctrlBlockBytes = ctrlBytes
7✔
2645
        } else {
687✔
2646
                ctrlBlockBytes = signDesc.ControlBlock
687✔
2647
        }
687✔
2648

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2874
        return anchorScriptTree.TaprootKey, nil
×
2875
}
2876

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

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

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

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

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

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

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

2924
        return witnessStack, nil
2✔
2925
}
2926

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

241,769✔
3047
        tweakScalar.Add(&basePriv.Key)
241,769✔
3048

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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