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

lightningnetwork / lnd / 8992481634

07 May 2024 09:20PM UTC coverage: 49.325% (-8.9%) from 58.246%
8992481634

push

github

web-flow
Merge pull request #8733 from lightningnetwork/0-18-branch-rc2

build: bump version to v0.18.0-beta.rc2

92557 of 187649 relevant lines covered (49.32%)

1.56 hits per line

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

77.36
/input/script_utils.go
1
package input
2

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

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

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

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

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

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

42
        return *pub
3✔
43
}
44

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

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

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

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

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

77
        return ecdsa.ParseDERSignature(rawSig)
3✔
78
}
79

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

197
        return witnessScript, wire.NewTxOut(amt, pkScript), nil
3✔
198
}
199

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

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

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

227
        txOut := wire.NewTxOut(amt, pkScript)
3✔
228

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

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

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

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

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

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

3✔
260
        return witness
3✔
261
}
262

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

279
        return found, index
3✔
280
}
281

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

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

3✔
334
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
335
                OfferedHtlcScriptSizeConfirmed,
3✔
336
        ))
3✔
337

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3✔
419
        return builder.Script()
3✔
420
}
421

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

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

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

×
447
        return witnessStack, nil
×
448
}
449

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

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

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

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

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

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

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

×
488
                return true, nil
×
489
        }
×
490

491
        return false, nil
×
492
}
493

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

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

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

3✔
515
        return witnessStack, nil
3✔
516
}
517

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

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

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

3✔
543
        return witnessStack, nil
3✔
544
}
545

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

3✔
555
        builder := txscript.NewScriptBuilder()
3✔
556

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

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

567
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
3✔
568
}
569

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

3✔
581
        builder := txscript.NewScriptBuilder()
3✔
582

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

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

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

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

607
        return txscript.NewBaseTapLeaf(successLeafScript), nil
3✔
608
}
609

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

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

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

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

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

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

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

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

642
        htlcType htlcType
643
}
644

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

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

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

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

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

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

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

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

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

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

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

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

3✔
741
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
3✔
742

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

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

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

3✔
794
        var hType htlcType
3✔
795
        if localCommit {
6✔
796
                hType = htlcLocalOutgoing
3✔
797
        } else {
6✔
798
                hType = htlcRemoteIncoming
3✔
799
        }
3✔
800

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

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

818
        return append(sigBytes, byte(sigHash))
3✔
819
}
820

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

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

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

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

847
                ctrlBlock = ctrlBytes
×
848
        } else {
3✔
849
                ctrlBlock = signDesc.ControlBlock
3✔
850
        }
3✔
851

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

3✔
860
        return witnessStack, nil
3✔
861
}
862

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

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

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

890
                ctrlBlockBytes = ctrlBytes
3✔
891
        } else {
3✔
892
                ctrlBlockBytes = signDesc.ControlBlock
3✔
893
        }
3✔
894

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

3✔
903
        return witnessStack, nil
3✔
904
}
905

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

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

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

3✔
922
        return witnessStack, nil
3✔
923
}
924

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

3✔
966
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
967
                AcceptedHtlcScriptSizeConfirmed,
3✔
968
        ))
3✔
969

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3✔
1060
        return builder.Script()
3✔
1061
}
1062

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

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

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

3✔
1095
        return witnessStack, nil
3✔
1096
}
1097

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

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

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

×
1122
        return witnessStack, nil
×
1123
}
1124

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

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

×
1138
        return revokeKey, nil
×
1139
}
1140

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

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

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

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

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

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

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

3✔
1196
        return witnessStack, nil
3✔
1197
}
1198

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

3✔
1209
        builder := txscript.NewScriptBuilder()
3✔
1210

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

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

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

1230
        return txscript.NewBaseTapLeaf(timeoutLeafScript), nil
3✔
1231
}
1232

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

3✔
1245
        builder := txscript.NewScriptBuilder()
3✔
1246

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

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

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

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

1270
        return txscript.NewBaseTapLeaf(successLeafScript), nil
3✔
1271
}
1272

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

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

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

3✔
1300
        tapScriptRoot := tapscriptTree.RootNode.TapHash()
3✔
1301

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

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

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

3✔
1353
        var hType htlcType
3✔
1354
        if ourCommit {
6✔
1355
                hType = htlcLocalIncoming
3✔
1356
        } else {
6✔
1357
                hType = htlcRemoteOutgoing
3✔
1358
        }
3✔
1359

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

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

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

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

1398
                ctrlBlock = ctrlBytes
3✔
1399
        } else {
3✔
1400
                ctrlBlock = signDesc.ControlBlock
3✔
1401
        }
3✔
1402

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

3✔
1413
        return witnessStack, nil
3✔
1414
}
1415

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

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

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

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

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

3✔
1467
        return witnessStack, nil
3✔
1468
}
1469

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

3✔
1476
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
1477
        if err != nil {
3✔
1478
                return nil, err
×
1479
        }
×
1480

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

3✔
1486
        return witnessStack, nil
3✔
1487
}
1488

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

3✔
1521
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
1522
                ToLocalScriptSize,
3✔
1523
        ))
3✔
1524

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

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

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

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

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

3✔
1549
        // Close out the if statement.
3✔
1550
        builder.AddOp(txscript.OP_ENDIF)
3✔
1551

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

3✔
1557
        return builder.Script()
3✔
1558
}
3✔
1559

1560
// TODO(roasbeef): move all taproot stuff to new file?
1561

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

3✔
1572
        builder := txscript.NewScriptBuilder()
3✔
1573

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

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

3✔
1585
        secondLevelLeafScript, err := builder.Script()
3✔
1586
        if err != nil {
3✔
1587
                return txscript.TapLeaf{}, err
×
1588
        }
×
1589

1590
        return txscript.NewBaseTapLeaf(secondLevelLeafScript), nil
3✔
1591
}
1592

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

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

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

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

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

1638
        tapScriptRoot := tapScriptTree.RootNode.TapHash()
×
1639

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

×
1647
        return redemptionKey, nil
×
1648
}
1649

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

1655
        // SuccessTapLeaf is the tapleaf for the redemption path.
1656
        SuccessTapLeaf txscript.TapLeaf
1657
}
1658

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

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

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

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

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

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

3✔
1704
        switch path {
3✔
1705
        case ScriptPathDelay:
×
1706
                fallthrough
×
1707
        case ScriptPathSuccess:
3✔
1708
                return s.SuccessTapLeaf.Script, nil
3✔
1709

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

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

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

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

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

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

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

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

×
1760
        return witnessStack, nil
×
1761
}
1762

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

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

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

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

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

3✔
1805
        return witnessStack, nil
3✔
1806
}
1807

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

3✔
1839
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(
3✔
1840
                ToLocalScriptSize + LeaseWitnessScriptSizeOverhead,
3✔
1841
        ))
3✔
1842

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

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

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

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

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

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

3✔
1874
        // Close out the if statement.
3✔
1875
        builder.AddOp(txscript.OP_ENDIF)
3✔
1876

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

3✔
1882
        return builder.Script()
3✔
1883
}
3✔
1884

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

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

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

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

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

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

×
1921
        return witnessStack, nil
×
1922
}
1923

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

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

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

×
1946
        return witnessStack, nil
×
1947
}
1948

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

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

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

3✔
1977
        return witnessStack, nil
3✔
1978
}
1979

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

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

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

3✔
2028
        builder.AddOp(txscript.OP_IF)
3✔
2029

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

3✔
2034
        builder.AddOp(txscript.OP_ELSE)
3✔
2035

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

3✔
2043
        builder.AddOp(txscript.OP_ENDIF)
3✔
2044

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

3✔
2049
        return builder.Script()
3✔
2050
}
3✔
2051

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

2058
        // SettleLeaf is the leaf used to settle the output after the delay.
2059
        SettleLeaf txscript.TapLeaf
2060

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3✔
2179
        return builder.Script()
3✔
2180
}
3✔
2181

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

3✔
2187
        builder := txscript.NewScriptBuilder()
3✔
2188
        builder.AddData(schnorr.SerializePubKey(selfKey))
3✔
2189
        builder.AddOp(txscript.OP_DROP)
3✔
2190
        builder.AddData(schnorr.SerializePubKey(revokeKey))
3✔
2191
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2192

3✔
2193
        return builder.Script()
3✔
2194
}
3✔
2195

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

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

2239
        return commitScriptTree.TaprootKey, nil
×
2240
}
2241

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

3✔
2248
        tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
3✔
2249
        scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
3✔
2250
        settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
3✔
2251

3✔
2252
        return settleMerkleProof.ToControlBlock(internalKey)
3✔
2253
}
3✔
2254

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

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

2278
                ctrlBlockBytes = ctrlBytes
×
2279
        } else {
3✔
2280
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2281
        }
3✔
2282

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

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

2301
        return witnessStack, nil
3✔
2302
}
2303

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

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

2322
                ctrlBlockBytes = revokeBytes
×
2323
        } else {
3✔
2324
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2325
        }
3✔
2326

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

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

3✔
2342
        return witnessStack, nil
3✔
2343
}
2344

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

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

3✔
2379
        builder.AddOp(txscript.OP_IF)
3✔
2380

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

3✔
2385
        builder.AddOp(txscript.OP_ELSE)
3✔
2386

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

3✔
2394
        builder.AddInt64(int64(csvTimeout))
3✔
2395
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2396
        builder.AddOp(txscript.OP_DROP)
3✔
2397

3✔
2398
        builder.AddData(selfKey.SerializeCompressed())
3✔
2399

3✔
2400
        builder.AddOp(txscript.OP_ENDIF)
3✔
2401

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

3✔
2406
        return builder.Script()
3✔
2407
}
3✔
2408

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

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

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

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

3✔
2442
        return witnessStack, nil
3✔
2443
}
2444

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

3✔
2455
        sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
3✔
2456
        if err != nil {
3✔
2457
                return nil, err
×
2458
        }
×
2459

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

3✔
2467
        return witnessStack, nil
3✔
2468
}
2469

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

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

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

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

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

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

2514
        return witness, nil
3✔
2515
}
2516

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

3✔
2528
        return builder.Script()
3✔
2529
}
3✔
2530

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

3✔
2548
        // Only the given key can spend the output.
3✔
2549
        builder.AddData(key.SerializeCompressed())
3✔
2550
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
2551

3✔
2552
        // Check that the it has one confirmation.
3✔
2553
        builder.AddOp(txscript.OP_1)
3✔
2554
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2555

3✔
2556
        return builder.Script()
3✔
2557
}
3✔
2558

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

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

3✔
2573
        remoteScript, err := builder.Script()
3✔
2574
        if err != nil {
3✔
2575
                return nil, err
×
2576
        }
×
2577

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

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

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

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

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

2621
        return commitScriptTree.TaprootKey, nil
×
2622
}
2623

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

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

2642
                ctrlBlockBytes = ctrlBytes
×
2643
        } else {
3✔
2644
                ctrlBlockBytes = signDesc.ControlBlock
3✔
2645
        }
3✔
2646

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

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

3✔
2662
        return witnessStack, nil
3✔
2663
}
2664

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

3✔
2681
        builder := txscript.NewScriptBuilder(txscript.WithScriptAllocSize(45))
3✔
2682

3✔
2683
        // Only the given key can spend the output.
3✔
2684
        builder.AddData(key.SerializeCompressed())
3✔
2685
        builder.AddOp(txscript.OP_CHECKSIGVERIFY)
3✔
2686

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

3✔
2694
        // Check that it has one confirmation.
3✔
2695
        builder.AddOp(txscript.OP_1)
3✔
2696
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2697

3✔
2698
        return builder.Script()
3✔
2699
}
3✔
2700

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

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

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

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

3✔
2725
        return witnessStack, nil
3✔
2726
}
2727

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

3✔
2747
        // Spend immediately with key.
3✔
2748
        builder.AddData(key.SerializeCompressed())
3✔
2749
        builder.AddOp(txscript.OP_CHECKSIG)
3✔
2750

3✔
2751
        // Duplicate the value if true, since it will be consumed by the NOTIF.
3✔
2752
        builder.AddOp(txscript.OP_IFDUP)
3✔
2753

3✔
2754
        // Otherwise spendable by anyone after 16 confirmations.
3✔
2755
        builder.AddOp(txscript.OP_NOTIF)
3✔
2756
        builder.AddOp(txscript.OP_16)
3✔
2757
        builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
3✔
2758
        builder.AddOp(txscript.OP_ENDIF)
3✔
2759

3✔
2760
        return builder.Script()
3✔
2761
}
3✔
2762

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

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

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

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

3✔
2783
        anchorScript, err := builder.Script()
3✔
2784
        if err != nil {
3✔
2785
                return nil, err
×
2786
        }
×
2787

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

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

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

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

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

3✔
2824
        switch path {
3✔
2825
        case ScriptPathDelay:
×
2826
                fallthrough
×
2827
        case ScriptPathSuccess:
3✔
2828
                return a.SweepLeaf.Script, nil
3✔
2829

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

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

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

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

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

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

2872
        return anchorScriptTree.TaprootKey, nil
×
2873
}
2874

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

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

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

3✔
2892
        return witnessStack, nil
3✔
2893
}
2894

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

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

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

2922
        return witnessStack, nil
×
2923
}
2924

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

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

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

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

3✔
2947
        return witnessStack, nil
3✔
2948
}
2949

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

×
2959
        return witnessStack, nil
×
2960
}
×
2961

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

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

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

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

3✔
3021
        pubKey.AsJacobian(&pubKeyJacobian)
3✔
3022
        btcec.AddNonConst(&pubKeyJacobian, &tweakJacobian, &resultJacobian)
3✔
3023

3✔
3024
        resultJacobian.ToAffine()
3✔
3025
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
3✔
3026
}
3✔
3027

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

3✔
3041
        // tweakInt := sha256(commitPoint || basePub)
3✔
3042
        tweakScalar := new(btcec.ModNScalar)
3✔
3043
        tweakScalar.SetByteSlice(commitTweak)
3✔
3044

3✔
3045
        tweakScalar.Add(&basePriv.Key)
3✔
3046

3✔
3047
        return &btcec.PrivateKey{Key: *tweakScalar}
3✔
3048
}
3✔
3049

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

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

3✔
3084
        var (
3✔
3085
                revokeBaseJacobian btcec.JacobianPoint
3✔
3086
                rJacobian          btcec.JacobianPoint
3✔
3087
        )
3✔
3088
        revokeBase.AsJacobian(&revokeBaseJacobian)
3✔
3089
        btcec.ScalarMultNonConst(
3✔
3090
                revokeTweakScalar, &revokeBaseJacobian, &rJacobian,
3✔
3091
        )
3✔
3092

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

3✔
3098
        var (
3✔
3099
                commitPointJacobian btcec.JacobianPoint
3✔
3100
                cJacobian           btcec.JacobianPoint
3✔
3101
        )
3✔
3102
        commitPoint.AsJacobian(&commitPointJacobian)
3✔
3103
        btcec.ScalarMultNonConst(
3✔
3104
                commitTweakScalar, &commitPointJacobian, &cJacobian,
3✔
3105
        )
3✔
3106

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

3✔
3114
        resultJacobian.ToAffine()
3✔
3115
        return btcec.NewPublicKey(&resultJacobian.X, &resultJacobian.Y)
3✔
3116
}
3✔
3117

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

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

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

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

3✔
3159
        revocationPriv := revokeHalfPriv.Add(commitHalfPriv)
3✔
3160

3✔
3161
        return &btcec.PrivateKey{Key: *revocationPriv}
3✔
3162
}
3✔
3163

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