2015-12-21 00:10:24 +01:00
|
|
|
package lnwallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2016-06-30 21:08:27 +02:00
|
|
|
"crypto/sha256"
|
2016-11-15 03:34:59 +01:00
|
|
|
"encoding/binary"
|
2015-12-21 00:10:24 +01:00
|
|
|
"fmt"
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
"math/big"
|
2015-12-21 00:10:24 +01:00
|
|
|
|
2016-06-30 21:08:27 +02:00
|
|
|
"golang.org/x/crypto/hkdf"
|
2017-07-30 03:01:05 +02:00
|
|
|
"golang.org/x/crypto/ripemd160"
|
2016-06-30 21:08:27 +02:00
|
|
|
|
2016-05-15 16:17:44 +02:00
|
|
|
"github.com/roasbeef/btcd/btcec"
|
2017-01-05 22:56:27 +01:00
|
|
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
2016-05-15 16:17:44 +02:00
|
|
|
"github.com/roasbeef/btcd/txscript"
|
|
|
|
"github.com/roasbeef/btcd/wire"
|
|
|
|
"github.com/roasbeef/btcutil"
|
2015-12-21 00:10:24 +01:00
|
|
|
)
|
|
|
|
|
2015-12-31 07:32:09 +01:00
|
|
|
var (
|
|
|
|
// TODO(roasbeef): remove these and use the one's defined in txscript
|
|
|
|
// within testnet-L.
|
2017-02-23 20:56:47 +01:00
|
|
|
|
2017-02-24 14:32:33 +01:00
|
|
|
// SequenceLockTimeSeconds is the 22nd bit which indicates the lock
|
|
|
|
// time is in seconds.
|
|
|
|
SequenceLockTimeSeconds = uint32(1 << 22)
|
|
|
|
|
2017-01-13 15:29:56 +01:00
|
|
|
// TimelockShift is used to make sure the commitment transaction is
|
|
|
|
// spendable by setting the locktime with it so that it is larger than
|
|
|
|
// 500,000,000, thus interpreting it as Unix epoch timestamp and not
|
|
|
|
// a block height. It is also smaller than the current timestamp which
|
|
|
|
// has bit (1 << 30) set, so there is no risk of having the commitment
|
|
|
|
// transaction be rejected. This way we can safely use the lower 24 bits
|
|
|
|
// of the locktime field for part of the obscured commitment transaction
|
|
|
|
// number.
|
|
|
|
TimelockShift = uint32(1 << 29)
|
2015-12-31 07:32:09 +01:00
|
|
|
)
|
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
const (
|
|
|
|
// StateHintSize is the total number of bytes used between the sequence
|
|
|
|
// number and locktime of the commitment transaction use to encode a hint
|
|
|
|
// to the state number of a particular commitment transaction.
|
2017-01-04 16:15:50 +01:00
|
|
|
StateHintSize = 6
|
2016-11-15 03:34:59 +01:00
|
|
|
|
|
|
|
// maxStateHint is the maximum state number we're able to encode using
|
|
|
|
// StateHintSize bytes amongst the sequence number and locktime fields
|
|
|
|
// of the commitment transaction.
|
2017-04-07 18:05:04 +02:00
|
|
|
maxStateHint uint64 = (1 << 48) - 1
|
2016-11-15 03:34:59 +01:00
|
|
|
)
|
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
// witnessScriptHash generates a pay-to-witness-script-hash public key script
|
|
|
|
// paying to a version 0 witness program paying to the passed redeem script.
|
2016-10-16 01:02:09 +02:00
|
|
|
func witnessScriptHash(witnessScript []byte) ([]byte, error) {
|
2015-12-21 00:10:24 +01:00
|
|
|
bldr := txscript.NewScriptBuilder()
|
2016-05-04 04:45:32 +02:00
|
|
|
|
|
|
|
bldr.AddOp(txscript.OP_0)
|
2017-03-16 02:56:25 +01:00
|
|
|
scriptHash := sha256.Sum256(witnessScript)
|
2016-05-04 04:45:32 +02:00
|
|
|
bldr.AddData(scriptHash[:])
|
2015-12-21 00:10:24 +01:00
|
|
|
return bldr.Script()
|
|
|
|
}
|
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
// genMultiSigScript generates the non-p2sh'd multisig script for 2 of 2
|
2015-12-21 00:10:24 +01:00
|
|
|
// pubkeys.
|
2016-05-04 04:45:32 +02:00
|
|
|
func genMultiSigScript(aPub, bPub []byte) ([]byte, error) {
|
2015-12-21 00:10:24 +01:00
|
|
|
if len(aPub) != 33 || len(bPub) != 33 {
|
|
|
|
return nil, fmt.Errorf("Pubkey size error. Compressed pubkeys only")
|
|
|
|
}
|
|
|
|
|
2015-12-29 06:55:36 +01:00
|
|
|
// Swap to sort pubkeys if needed. Keys are sorted in lexicographical
|
|
|
|
// order. The signatures within the scriptSig must also adhere to the
|
2017-05-11 02:43:11 +02:00
|
|
|
// order, ensuring that the signatures for each public key appears in
|
|
|
|
// the proper order on the stack.
|
2015-12-29 06:55:36 +01:00
|
|
|
if bytes.Compare(aPub, bPub) == -1 {
|
2015-12-21 00:10:24 +01:00
|
|
|
aPub, bPub = bPub, aPub
|
|
|
|
}
|
|
|
|
|
|
|
|
bldr := txscript.NewScriptBuilder()
|
|
|
|
bldr.AddOp(txscript.OP_2)
|
2015-12-29 06:55:36 +01:00
|
|
|
bldr.AddData(aPub) // Add both pubkeys (sorted).
|
2015-12-21 00:10:24 +01:00
|
|
|
bldr.AddData(bPub)
|
|
|
|
bldr.AddOp(txscript.OP_2)
|
|
|
|
bldr.AddOp(txscript.OP_CHECKMULTISIG)
|
|
|
|
return bldr.Script()
|
|
|
|
}
|
|
|
|
|
2016-08-13 00:37:35 +02:00
|
|
|
// GenFundingPkScript creates a redeem script, and its matching p2wsh
|
2016-05-04 04:45:32 +02:00
|
|
|
// output for the funding transaction.
|
2016-08-13 00:37:35 +02:00
|
|
|
func GenFundingPkScript(aPub, bPub []byte, amt int64) ([]byte, *wire.TxOut, error) {
|
2016-05-04 04:45:32 +02:00
|
|
|
// As a sanity check, ensure that the passed amount is above zero.
|
|
|
|
if amt <= 0 {
|
2015-12-29 06:55:36 +01:00
|
|
|
return nil, nil, fmt.Errorf("can't create FundTx script with " +
|
2016-05-04 04:45:32 +02:00
|
|
|
"zero, or negative coins")
|
2015-12-21 00:10:24 +01:00
|
|
|
}
|
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
// First, create the 2-of-2 multi-sig script itself.
|
2016-10-16 01:02:09 +02:00
|
|
|
witnessScript, err := genMultiSigScript(aPub, bPub)
|
2015-12-21 00:10:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2016-02-05 21:33:22 +01:00
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
// With the 2-of-2 script in had, generate a p2wsh script which pays
|
|
|
|
// to the funding script.
|
2016-10-16 01:02:09 +02:00
|
|
|
pkScript, err := witnessScriptHash(witnessScript)
|
2015-12-21 00:10:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2016-10-16 01:02:09 +02:00
|
|
|
return witnessScript, wire.NewTxOut(amt, pkScript), nil
|
2015-12-21 00:10:24 +01:00
|
|
|
}
|
|
|
|
|
2016-09-09 02:04:08 +02:00
|
|
|
// SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh
|
2015-12-29 06:55:36 +01:00
|
|
|
// multi-sig output.
|
2016-10-16 01:02:09 +02:00
|
|
|
func SpendMultiSig(witnessScript, pubA, sigA, pubB, sigB []byte) [][]byte {
|
2016-05-04 04:45:32 +02:00
|
|
|
witness := make([][]byte, 4)
|
2015-12-21 00:10:24 +01:00
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
// When spending a p2wsh multi-sig script, rather than an OP_0, we add
|
|
|
|
// a nil stack element to eat the extra pop.
|
|
|
|
witness[0] = nil
|
2015-12-21 00:10:24 +01:00
|
|
|
|
2016-10-16 01:02:09 +02:00
|
|
|
// When initially generating the witnessScript, we sorted the serialized
|
2016-02-05 21:33:22 +01:00
|
|
|
// public keys in descending order. So we do a quick comparison in order
|
2016-10-16 01:02:09 +02:00
|
|
|
// ensure the signatures appear on the Script Virtual Machine stack in
|
2016-02-05 21:33:22 +01:00
|
|
|
// the correct order.
|
|
|
|
if bytes.Compare(pubA, pubB) == -1 {
|
2016-05-04 04:45:32 +02:00
|
|
|
witness[1] = sigB
|
|
|
|
witness[2] = sigA
|
2016-02-05 21:33:22 +01:00
|
|
|
} else {
|
2016-05-04 04:45:32 +02:00
|
|
|
witness[1] = sigA
|
|
|
|
witness[2] = sigB
|
2016-02-05 21:33:22 +01:00
|
|
|
}
|
2015-12-21 00:10:24 +01:00
|
|
|
|
2017-01-13 06:01:50 +01:00
|
|
|
// Finally, add the preimage as the last witness element.
|
2016-10-16 01:02:09 +02:00
|
|
|
witness[3] = witnessScript
|
2015-12-21 00:10:24 +01:00
|
|
|
|
2016-05-04 04:45:32 +02:00
|
|
|
return witness
|
2015-12-21 00:10:24 +01:00
|
|
|
}
|
2015-12-21 04:47:29 +01:00
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
// FindScriptOutputIndex finds the index of the public key script output
|
|
|
|
// matching 'script'. Additionally, a boolean is returned indicating if a
|
|
|
|
// matching output was found at all.
|
|
|
|
//
|
2015-12-29 06:55:36 +01:00
|
|
|
// NOTE: The search stops after the first matching script is found.
|
2016-08-13 00:37:35 +02:00
|
|
|
func FindScriptOutputIndex(tx *wire.MsgTx, script []byte) (bool, uint32) {
|
2015-12-21 04:47:29 +01:00
|
|
|
found := false
|
|
|
|
index := uint32(0)
|
|
|
|
for i, txOut := range tx.TxOut {
|
|
|
|
if bytes.Equal(txOut.PkScript, script) {
|
|
|
|
found = true
|
|
|
|
index = uint32(i)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found, index
|
|
|
|
}
|
2015-12-31 07:32:09 +01:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// ripemd160H calculates the ripemd160 of the passed byte slice. This is used to
|
|
|
|
// calculate the intermediate hash for payment pre-images. Payment hashes are
|
|
|
|
// the result of ripemd160(sha256(paymentPreimage)). As a result, the value
|
|
|
|
// passed in should be the sha256 of the payment hash.
|
|
|
|
func ripemd160H(d []byte) []byte {
|
|
|
|
h := ripemd160.New()
|
|
|
|
h.Write(d)
|
|
|
|
return h.Sum(nil)
|
|
|
|
}
|
|
|
|
|
2016-01-02 21:10:14 +01:00
|
|
|
// senderHTLCScript constructs the public key script for an outgoing HTLC
|
2017-07-30 03:01:05 +02:00
|
|
|
// output payment for the sender's version of the commitment transaction. The
|
|
|
|
// possible script paths from this output include:
|
|
|
|
//
|
|
|
|
// * The sender timing out the HTLC using the second level HTLC timeout
|
|
|
|
// transaction.
|
|
|
|
// * The receiver of the HTLC claiming the output on-chain with the payment
|
|
|
|
// preimage.
|
|
|
|
// * The receiver of the HTLC sweeping all the funds in the case that a
|
|
|
|
// revoked commitment transaction bearing this HTLC was broadcast.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// Possible Input Scripts:
|
2017-07-30 03:01:05 +02:00
|
|
|
// SENDR: <0> <sendr sig> <recvr sig> <0> (spend using HTLC timeout transaction)
|
|
|
|
// RECVR: <recvr sig> <preimage>
|
|
|
|
// REVOK: <revoke sig> <revoke key>
|
2016-07-23 03:52:36 +02:00
|
|
|
// * receiver revoke
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
2017-07-30 03:01:05 +02:00
|
|
|
// OP_DUP OP_HASH160 <revocation key hash160> OP_EQUAL
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// OP_IF
|
2017-07-30 03:01:05 +02:00
|
|
|
// OP_CHECKSIG
|
|
|
|
// OP_ELSE
|
|
|
|
// <recv key>
|
|
|
|
// OP_SWAP OP_SIZE 32 OP_EQUAL
|
|
|
|
// OP_NOTIF
|
|
|
|
// OP_DROP 2 OP_SWAP <sender key> 2 OP_CHECKMULTISIG
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// OP_ELSE
|
2017-07-30 03:01:05 +02:00
|
|
|
// OP_HASH160 <ripemd160(payment hash)> OP_EQUALVERIFY
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// OP_ENDIF
|
|
|
|
// OP_ENDIF
|
2017-07-30 03:01:05 +02:00
|
|
|
func senderHTLCScript(senderKey, receiverKey, revocationKey *btcec.PublicKey,
|
|
|
|
paymentHash []byte) ([]byte, error) {
|
2015-12-31 07:32:09 +01:00
|
|
|
|
|
|
|
builder := txscript.NewScriptBuilder()
|
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// The opening operations are used to determine if this is the receiver
|
|
|
|
// of the HTLC attempting to sweep all the funds due to a contract
|
|
|
|
// breach. In this case, they'll place the revocation key at the top of
|
|
|
|
// the stack.
|
|
|
|
builder.AddOp(txscript.OP_DUP)
|
|
|
|
builder.AddOp(txscript.OP_HASH160)
|
|
|
|
builder.AddData(btcutil.Hash160(revocationKey.SerializeCompressed()))
|
|
|
|
builder.AddOp(txscript.OP_EQUAL)
|
|
|
|
|
|
|
|
// If the hash matches, then this is the revocation clause. The output
|
|
|
|
// can be spent if the check sig operation passes.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_IF)
|
2017-07-30 03:01:05 +02:00
|
|
|
builder.AddOp(txscript.OP_CHECKSIG)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// Otherwise, this may either be the receiver of the HTLC claiming with
|
|
|
|
// the pre-image, or the sender of the HTLC sweeping the output after
|
|
|
|
// it has timed out.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_ELSE)
|
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// We'll do a bit of set up by pushing the receiver's key on the top of
|
|
|
|
// the stack. This will be needed later if we decide that this is the
|
|
|
|
// sender activating the time out clause with the HTLC timeout
|
|
|
|
// transaction.
|
|
|
|
builder.AddData(receiverKey.SerializeCompressed())
|
2015-12-31 07:32:09 +01:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// Atm, the top item of the stack is the receiverKey's so we use a swap
|
|
|
|
// to expose what is either the payment pre-image or a signature.
|
|
|
|
builder.AddOp(txscript.OP_SWAP)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// With the top item swapped, check if it's 32 bytes. If so, then this
|
|
|
|
// *may* be the payment pre-image.
|
|
|
|
builder.AddOp(txscript.OP_SIZE)
|
|
|
|
builder.AddInt64(32)
|
|
|
|
builder.AddOp(txscript.OP_EQUAL)
|
|
|
|
|
|
|
|
// If it isn't then this might be the sender of the HTLC activating the
|
|
|
|
// time out clause.
|
|
|
|
builder.AddOp(txscript.OP_NOTIF)
|
|
|
|
|
|
|
|
// We'll drop the OP_IF return value off the top of the stack so we can
|
|
|
|
// reconstruct the multi-sig script used as an off-chain covenant. If
|
|
|
|
// two valid signatures are provided, ten then output will be deemed as
|
|
|
|
// spendable.
|
|
|
|
builder.AddOp(txscript.OP_DROP)
|
|
|
|
builder.AddOp(txscript.OP_2)
|
|
|
|
builder.AddOp(txscript.OP_SWAP)
|
|
|
|
builder.AddData(senderKey.SerializeCompressed())
|
|
|
|
builder.AddOp(txscript.OP_2)
|
|
|
|
builder.AddOp(txscript.OP_CHECKMULTISIG)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// Otherwise, then the only other case is that this is the receiver of
|
|
|
|
// the HTLC sweeping it on-chain with the payment pre-image.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_ELSE)
|
2015-12-31 07:32:09 +01:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// Hash the top item of the stack and compare it with the hash160 of
|
|
|
|
// the payment hash, which is already the sha256 of the payment
|
|
|
|
// pre-image. By using this little trick we're able save space on-chain
|
|
|
|
// as the witness includes a 20-byte hash rather than a 32-byte hash.
|
|
|
|
builder.AddOp(txscript.OP_HASH160)
|
|
|
|
builder.AddData(ripemd160H(paymentHash))
|
|
|
|
builder.AddOp(txscript.OP_EQUALVERIFY)
|
|
|
|
|
|
|
|
// Close out the OP_IF statement above.
|
|
|
|
builder.AddOp(txscript.OP_ENDIF)
|
2015-12-31 07:32:09 +01:00
|
|
|
|
2017-07-30 03:01:05 +02:00
|
|
|
// Close out the OP_IF statement at the top of the script.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_ENDIF)
|
|
|
|
|
2015-12-31 07:32:09 +01:00
|
|
|
return builder.Script()
|
|
|
|
}
|
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
// senderHtlcSpendRevoke constructs a valid witness allowing the receiver of an
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// HTLC to claim the output with knowledge of the revocation preimage in the
|
|
|
|
// scenario that the sender of the HTLC broadcasts a previously revoked
|
2017-01-13 06:01:50 +01:00
|
|
|
// commitment transaction. A valid spend requires knowledge of the preimage to
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// the commitment transaction's revocation hash, and a valid signature under
|
|
|
|
// the receiver's public key.
|
|
|
|
func senderHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
revokePreimage []byte) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, reciverKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// In order to force script execution to enter the revocation clause,
|
2016-11-15 03:34:59 +01:00
|
|
|
// we place two one's as the first items in the final evaluated witness
|
|
|
|
// stack.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 5))
|
|
|
|
witnessStack[0] = sweepSig
|
|
|
|
witnessStack[1] = revokePreimage
|
|
|
|
witnessStack[2] = []byte{1}
|
|
|
|
witnessStack[3] = []byte{1}
|
|
|
|
witnessStack[4] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// senderHtlcSpendRedeem constructs a valid witness allowing the receiver of an
|
|
|
|
// HTLC to redeem the pending output in the scenario that the sender broadcasts
|
|
|
|
// their version of the commitment transaction. A valid spend requires
|
2017-01-13 06:01:50 +01:00
|
|
|
// knowledge of the payment preimage, and a valid signature under the
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// receivers public key.
|
|
|
|
func senderHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
paymentPreimage []byte) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, reciverKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We force script execution into the HTLC redemption clause by placing
|
2016-11-15 03:34:59 +01:00
|
|
|
// a one, then a zero as the first items in the final evaluated
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// witness stack.
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 5))
|
|
|
|
witnessStack[0] = sweepSig
|
|
|
|
witnessStack[1] = paymentPreimage
|
2017-05-18 20:58:19 +02:00
|
|
|
witnessStack[2] = nil
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack[3] = []byte{1}
|
|
|
|
witnessStack[4] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// htlcSpendTimeout constructs a valid witness allowing the sender of an HTLC
|
|
|
|
// to recover the pending funds after an absolute, then relative locktime
|
|
|
|
// period.
|
|
|
|
func senderHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
absoluteTimeout, relativeTimeout uint32) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
// Since the HTLC output has an absolute timeout before we're permitted
|
2016-11-15 03:34:59 +01:00
|
|
|
// to sweep the output, we need to set the locktime of this sweeping
|
|
|
|
// transaction to that absolute value in order to pass Script
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// verification.
|
|
|
|
sweepTx.LockTime = absoluteTimeout
|
|
|
|
|
|
|
|
// Additionally, we're required to wait a relative period of time
|
|
|
|
// before we can sweep the output in order to allow the other party to
|
|
|
|
// contest our claim of validity to this version of the commitment
|
|
|
|
// transaction.
|
|
|
|
sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, relativeTimeout)
|
|
|
|
|
|
|
|
// Finally, OP_CSV requires that the version of the transaction
|
|
|
|
// spending a pkscript with OP_CSV within it *must* be >= 2.
|
|
|
|
sweepTx.Version = 2
|
|
|
|
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, senderKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We place a zero as the first item of the evaluated witness stack in
|
|
|
|
// order to force Script execution to the HTLC timeout clause.
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 3))
|
|
|
|
witnessStack[0] = sweepSig
|
2017-05-18 20:58:19 +02:00
|
|
|
witnessStack[1] = nil
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack[2] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// receiverHTLCScript constructs the public key script for an incoming HTLC
|
|
|
|
// output payment for the receiver's version of the commitment transaction:
|
|
|
|
//
|
|
|
|
// Possible Input Scripts:
|
|
|
|
// RECVR: <sig> <preimage> 1
|
2016-10-26 14:25:42 +02:00
|
|
|
// REVOK: <sig> <preimage> 0 1
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// SENDR: <sig> 0 0
|
|
|
|
//
|
|
|
|
// OP_IF
|
|
|
|
// //Receiver
|
|
|
|
// OP_SIZE 32 OP_EQUALVERIFY
|
|
|
|
// OP_SHA256
|
|
|
|
// <payment hash> OP_EQUALVERIFY
|
|
|
|
// <relative blockheight> OP_CHECKSEQUENCEVERIFY OP_DROP
|
|
|
|
// <receiver key> OP_CHECKSIG
|
|
|
|
// OP_ELSE
|
|
|
|
// //Sender
|
|
|
|
// OP_IF
|
|
|
|
// //Revocation
|
|
|
|
// OP_SHA256
|
|
|
|
// <revoke hash> OP_EQUALVERIFY
|
|
|
|
// OP_ELSE
|
|
|
|
// //Refund
|
2016-10-26 14:25:42 +02:00
|
|
|
// <absolute blockheight> OP_CHECKLOCKTIMEVERIFY OP_DROP
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// OP_ENDIF
|
|
|
|
// <sender key> OP_CHECKSIG
|
|
|
|
// OP_ENDIF
|
2016-07-13 02:35:51 +02:00
|
|
|
// TODO(roasbeef): go back to revocation keys in the HTLC outputs?
|
2017-01-13 06:01:50 +01:00
|
|
|
// * also could combine preimage with their key?
|
2015-12-31 07:32:09 +01:00
|
|
|
func receiverHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
|
|
|
|
receiverKey *btcec.PublicKey, revokeHash, paymentHash []byte) ([]byte, error) {
|
|
|
|
|
|
|
|
builder := txscript.NewScriptBuilder()
|
|
|
|
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// The receiver of the script will place a 1 as the first item of the
|
|
|
|
// witness stack forcing Script execution to enter the "if" clause of
|
|
|
|
// the main body of the script.
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddOp(txscript.OP_IF)
|
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
// In this clause, the receiver can redeem the HTLC after a relative
|
|
|
|
// timeout. This added delay gives the sender (at this time) an
|
|
|
|
// opportunity to re-claim the pending HTLC in the event that the
|
|
|
|
// receiver (at this time) broadcasts this old commitment transaction
|
|
|
|
// after it has been revoked. Additionally, we require that the
|
2017-01-13 06:01:50 +01:00
|
|
|
// preimage is exactly 32-bytes in order to avoid undesirable
|
2016-11-15 03:34:59 +01:00
|
|
|
// redemption asymmetries in the multi-hop scenario.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_SIZE)
|
|
|
|
builder.AddInt64(32)
|
|
|
|
builder.AddOp(txscript.OP_EQUALVERIFY)
|
|
|
|
builder.AddOp(txscript.OP_SHA256)
|
|
|
|
builder.AddData(paymentHash)
|
|
|
|
builder.AddOp(txscript.OP_EQUALVERIFY)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddInt64(int64(relativeTimeout))
|
2017-05-03 09:48:50 +02:00
|
|
|
builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_DROP)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddData(receiverKey.SerializeCompressed())
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_CHECKSIG)
|
2015-12-31 07:32:09 +01:00
|
|
|
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// Otherwise, the sender will place a 0 as the first item of the
|
2016-11-15 03:34:59 +01:00
|
|
|
// witness stack forcing execution to enter the "else" clause of the
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// main body of the script.
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddOp(txscript.OP_ELSE)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
// The sender will place a 1 as the second item of the witness stack in
|
|
|
|
// the scenario that the receiver broadcasts an invalidated commitment
|
|
|
|
// transaction, allowing the sender to sweep all the receiver's funds.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_IF)
|
|
|
|
builder.AddOp(txscript.OP_SHA256)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddData(revokeHash)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_EQUALVERIFY)
|
2015-12-31 07:32:09 +01:00
|
|
|
|
2016-01-02 21:10:14 +01:00
|
|
|
// If not, then the sender needs to wait for the HTLC timeout. This
|
|
|
|
// clause may be executed if the receiver fails to present the r-value
|
|
|
|
// in time. This prevents the pending funds from being locked up
|
2016-11-15 03:34:59 +01:00
|
|
|
// indefinitely.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
// The sender will place a 0 as the second item of the witness stack if
|
|
|
|
// they wish to sweep the HTLC after an absolute refund timeout. This
|
|
|
|
// time out clause prevents the pending funds from being locked up
|
2016-11-15 03:34:59 +01:00
|
|
|
// indefinitely.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_ELSE)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddInt64(int64(absoluteTimeout))
|
2016-01-19 09:19:16 +01:00
|
|
|
builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddOp(txscript.OP_DROP)
|
|
|
|
builder.AddOp(txscript.OP_ENDIF)
|
|
|
|
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// In either case, we also require a valid signature with the sender's
|
|
|
|
// commitment private key.
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddData(senderKey.SerializeCompressed())
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_CHECKSIG)
|
2015-12-31 07:32:09 +01:00
|
|
|
|
|
|
|
builder.AddOp(txscript.OP_ENDIF)
|
|
|
|
|
|
|
|
return builder.Script()
|
|
|
|
}
|
|
|
|
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// receiverHtlcSpendRedeem constructs a valid witness allowing the receiver of
|
|
|
|
// an HTLC to redeem the conditional payment in the event that their commitment
|
|
|
|
// transaction is broadcast. Since this is a pay out to the receiving party as
|
|
|
|
// an output on their commitment transaction, a relative time delay is required
|
|
|
|
// before the output can be spent.
|
|
|
|
func receiverHtlcSpendRedeem(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
reciverKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
paymentPreimage []byte, relativeTimeout uint32) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
// In order to properly spend the transaction, we need to set the
|
2016-11-15 03:34:59 +01:00
|
|
|
// sequence number. We do this by converting the relative block delay
|
|
|
|
// into a sequence number value able to be interpreted by
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// OP_CHECKSEQUENCEVERIFY.
|
|
|
|
sweepTx.TxIn[0].Sequence = lockTimeToSequence(false, relativeTimeout)
|
|
|
|
|
|
|
|
// Additionally, OP_CSV requires that the version of the transaction
|
|
|
|
// spending a pkscript with OP_CSV within it *must* be >= 2.
|
|
|
|
sweepTx.Version = 2
|
|
|
|
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, reciverKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Place a one as the first item in the evaluated witness stack to
|
|
|
|
// force script execution to the HTLC redemption clause.
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 4))
|
|
|
|
witnessStack[0] = sweepSig
|
|
|
|
witnessStack[1] = paymentPreimage
|
|
|
|
witnessStack[2] = []byte{1}
|
|
|
|
witnessStack[3] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// receiverHtlcSpendRevoke constructs a valid witness allowing the sender of an
|
|
|
|
// HTLC within a previously revoked commitment transaction to re-claim the
|
|
|
|
// pending funds in the case that the receiver broadcasts this revoked
|
|
|
|
// commitment transaction.
|
|
|
|
func receiverHtlcSpendRevoke(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
revokePreimage []byte) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
// TODO(roasbeef): move sig generate outside func, or just factor out?
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, senderKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We place a zero, then one as the first items in the evaluated
|
|
|
|
// witness stack in order to force script execution to the HTLC
|
|
|
|
// revocation clause.
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 5))
|
|
|
|
witnessStack[0] = sweepSig
|
|
|
|
witnessStack[1] = revokePreimage
|
|
|
|
witnessStack[2] = []byte{1}
|
2017-05-18 20:58:19 +02:00
|
|
|
witnessStack[3] = nil
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack[4] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// receiverHtlcSpendTimeout constructs a valid witness allowing the sender of
|
|
|
|
// an HTLC to recover the pending funds after an absolute timeout in the
|
|
|
|
// scenario that the receiver of the HTLC broadcasts their version of the
|
|
|
|
// commitment transaction.
|
|
|
|
func receiverHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount,
|
|
|
|
senderKey *btcec.PrivateKey, sweepTx *wire.MsgTx,
|
|
|
|
absoluteTimeout uint32) (wire.TxWitness, error) {
|
|
|
|
|
|
|
|
// The HTLC output has an absolute time period before we are permitted
|
|
|
|
// to recover the pending funds. Therefore we need to set the locktime
|
|
|
|
// on this sweeping transaction in order to pass Script verification.
|
|
|
|
sweepTx.LockTime = absoluteTimeout
|
|
|
|
|
|
|
|
hashCache := txscript.NewTxSigHashes(sweepTx)
|
|
|
|
sweepSig, err := txscript.RawTxInWitnessSignature(
|
|
|
|
sweepTx, hashCache, 0, int64(outputAmt), commitScript,
|
|
|
|
txscript.SigHashAll, senderKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 4))
|
|
|
|
witnessStack[0] = sweepSig
|
2017-05-18 20:58:19 +02:00
|
|
|
witnessStack[1] = nil
|
|
|
|
witnessStack[2] = nil
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack[3] = commitScript
|
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
2016-02-06 05:24:17 +01:00
|
|
|
// lockTimeToSequence converts the passed relative locktime to a sequence
|
|
|
|
// number in accordance to BIP-68.
|
|
|
|
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
|
|
|
|
// * (Compatibility)
|
|
|
|
func lockTimeToSequence(isSeconds bool, locktime uint32) uint32 {
|
|
|
|
if !isSeconds {
|
2016-08-26 01:25:23 +02:00
|
|
|
// The locktime is to be expressed in confirmations.
|
|
|
|
return locktime
|
2016-02-06 05:24:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the 22nd bit which indicates the lock time is in seconds, then
|
|
|
|
// shift the locktime over by 9 since the time granularity is in
|
|
|
|
// 512-second intervals (2^9). This results in a max lock-time of
|
|
|
|
// 33,554,431 seconds, or 1.06 years.
|
|
|
|
return SequenceLockTimeSeconds | (locktime >> 9)
|
|
|
|
}
|
|
|
|
|
2016-01-02 21:10:14 +01:00
|
|
|
// commitScriptToSelf constructs the public key script for the output on the
|
|
|
|
// commitment transaction paying to the "owner" of said commitment transaction.
|
2017-01-13 06:01:50 +01:00
|
|
|
// If the other party learns of the preimage to the revocation hash, then they
|
2016-01-02 21:10:14 +01:00
|
|
|
// can claim all the settled funds in the channel, plus the unsettled funds.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// Possible Input Scripts:
|
|
|
|
// REVOKE: <sig> 1
|
2017-02-04 00:28:13 +01:00
|
|
|
// SENDRSWEEP: <sig> <emptyvector>
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// Output Script:
|
|
|
|
// OP_IF
|
|
|
|
// <revokeKey> OP_CHECKSIG
|
|
|
|
// OP_ELSE
|
|
|
|
// <timeKey> OP_CHECKSIGVERIFY
|
|
|
|
// <numRelativeBlocks> OP_CHECKSEQUENCEVERIFY
|
|
|
|
// OP_ENDIF
|
|
|
|
func commitScriptToSelf(csvTimeout uint32, selfKey, revokeKey *btcec.PublicKey) ([]byte, error) {
|
2016-11-15 03:34:59 +01:00
|
|
|
// This script is spendable under two conditions: either the
|
|
|
|
// 'csvTimeout' has passed and we can redeem our funds, or they can
|
|
|
|
// produce a valid signature with the revocation public key. The
|
|
|
|
// revocation public key will *only* be known to the other party if we
|
|
|
|
// have divulged the revocation hash, allowing them to homomorphically
|
|
|
|
// derive the proper private key which corresponds to the revoke public
|
|
|
|
// key.
|
2015-12-31 07:32:09 +01:00
|
|
|
builder := txscript.NewScriptBuilder()
|
|
|
|
|
|
|
|
builder.AddOp(txscript.OP_IF)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
// If a valid signature using the revocation key is presented, then
|
|
|
|
// allow an immediate spend provided the proper signature.
|
|
|
|
builder.AddData(revokeKey.SerializeCompressed())
|
|
|
|
builder.AddOp(txscript.OP_CHECKSIG)
|
|
|
|
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddOp(txscript.OP_ELSE)
|
|
|
|
|
|
|
|
// Otherwise, we can re-claim our funds after a CSV delay of
|
|
|
|
// 'csvTimeout' timeout blocks, and a valid signature.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddData(selfKey.SerializeCompressed())
|
|
|
|
builder.AddOp(txscript.OP_CHECKSIGVERIFY)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddInt64(int64(csvTimeout))
|
2017-05-03 09:48:50 +02:00
|
|
|
builder.AddOp(txscript.OP_CHECKSEQUENCEVERIFY)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddOp(txscript.OP_ENDIF)
|
|
|
|
|
|
|
|
return builder.Script()
|
|
|
|
}
|
|
|
|
|
2016-01-02 21:10:14 +01:00
|
|
|
// commitScriptUnencumbered constructs the public key script on the commitment
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// transaction paying to the "other" party. The constructed output is a normal
|
|
|
|
// p2wkh output spendable immediately, requiring no contestation period.
|
2015-12-31 07:32:09 +01:00
|
|
|
func commitScriptUnencumbered(key *btcec.PublicKey) ([]byte, error) {
|
|
|
|
// This script goes to the "other" party, and it spendable immediately.
|
|
|
|
builder := txscript.NewScriptBuilder()
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
builder.AddOp(txscript.OP_0)
|
2015-12-31 07:32:09 +01:00
|
|
|
builder.AddData(btcutil.Hash160(key.SerializeCompressed()))
|
|
|
|
|
|
|
|
return builder.Script()
|
|
|
|
}
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2016-09-09 02:04:08 +02:00
|
|
|
// CommitSpendTimeout constructs a valid witness allowing the owner of a
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// particular commitment transaction to spend the output returning settled
|
2016-09-10 22:48:36 +02:00
|
|
|
// funds back to themselves after a relative block timeout. In order to
|
|
|
|
// properly spend the transaction, the target input's sequence number should be
|
|
|
|
// set accordingly based off of the target relative block timeout within the
|
|
|
|
// redeem script. Additionally, OP_CSV requires that the version of the
|
|
|
|
// transaction spending a pkscript with OP_CSV within it *must* be >= 2.
|
2016-09-09 02:04:08 +02:00
|
|
|
func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
|
2016-09-10 22:48:36 +02:00
|
|
|
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
2016-09-09 02:04:08 +02:00
|
|
|
|
2016-09-10 22:48:36 +02:00
|
|
|
// Ensure the transaction version supports the validation of sequence
|
|
|
|
// locks and CSV semantics.
|
|
|
|
if sweepTx.Version < 2 {
|
|
|
|
return nil, fmt.Errorf("version of passed transaction MUST "+
|
|
|
|
"be >= 2, not %v", sweepTx.Version)
|
|
|
|
}
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
// With the sequence number in place, we're now able to properly sign
|
|
|
|
// off on the sweep transaction.
|
2016-09-09 02:04:08 +02:00
|
|
|
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-02-04 00:28:13 +01:00
|
|
|
// Place an empty byte as the first item in the evaluated witness stack
|
|
|
|
// to force script execution to the timeout spend clause. We need to
|
|
|
|
// place an empty byte in order to ensure our script is still valid
|
|
|
|
// from the PoV of nodes that are enforcing minimal OP_IF/OP_NOTIF.
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 3))
|
2016-09-09 02:04:08 +02:00
|
|
|
witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
|
2017-02-04 00:28:13 +01:00
|
|
|
witnessStack[1] = nil
|
2016-10-16 01:02:09 +02:00
|
|
|
witnessStack[2] = signDesc.WitnessScript
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:23:26 +01:00
|
|
|
// CommitSpendRevoke constructs a valid witness allowing a node to sweep the
|
2017-01-13 06:01:50 +01:00
|
|
|
// settled output of a malicious counterparty who broadcasts a revoked
|
2016-11-15 03:34:59 +01:00
|
|
|
// commitment transaction.
|
2016-11-19 00:23:26 +01:00
|
|
|
func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
|
|
|
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2016-11-19 00:23:26 +01:00
|
|
|
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Place a 1 as the first item in the evaluated witness stack to
|
|
|
|
// force script execution to the revocation clause.
|
|
|
|
witnessStack := wire.TxWitness(make([][]byte, 3))
|
2016-11-19 00:23:26 +01:00
|
|
|
witnessStack[0] = append(sweepSig, byte(txscript.SigHashAll))
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
witnessStack[1] = []byte{1}
|
2016-11-19 00:23:26 +01:00
|
|
|
witnessStack[2] = signDesc.WitnessScript
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
return witnessStack, nil
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:23:26 +01:00
|
|
|
// CommitSpendNoDelay constructs a valid witness allowing a node to spend their
|
2017-01-13 06:01:50 +01:00
|
|
|
// settled no-delay output on the counterparty's commitment transaction.
|
2016-11-19 00:23:26 +01:00
|
|
|
func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
|
|
|
|
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
// This is just a regular p2wkh spend which looks something like:
|
|
|
|
// * witness: <sig> <pubkey>
|
2016-11-19 00:23:26 +01:00
|
|
|
inputScript, err := signer.ComputeInputScript(sweepTx, signDesc)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:23:26 +01:00
|
|
|
return wire.TxWitness(inputScript.Witness), nil
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
}
|
|
|
|
|
2017-07-30 03:00:23 +02:00
|
|
|
// SingleTweakBytes computes set of bytes we call the single tweak. The purpose
|
|
|
|
// of the single tweak is to randomize all regular delay and payment base
|
|
|
|
// points. To do this, we generate a hash that binds the commitment point to
|
|
|
|
// the pay/delay base point. The end end results is that the basePoint is
|
|
|
|
// tweaked as follows:
|
|
|
|
//
|
|
|
|
// * key = basePoint + sha256(commitPoint || basePoint)*G
|
|
|
|
func SingleTweakBytes(commitPoint, basePoint *btcec.PublicKey) []byte {
|
|
|
|
h := sha256.New()
|
|
|
|
h.Write(commitPoint.SerializeCompressed())
|
|
|
|
h.Write(basePoint.SerializeCompressed())
|
|
|
|
return h.Sum(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TweakPubKey tweaks a public base point given a per commitment point. The per
|
|
|
|
// commitment point is a unique point on our target curve for each commitment
|
|
|
|
// transaction. When tweaking a local base point for use in a remote commitment
|
|
|
|
// transaction, the remote party's current per commitment point is to be used.
|
|
|
|
// The opposite applies for when tweaking remote keys. Precisely, the following
|
|
|
|
// operation is used to "tweak" public keys:
|
|
|
|
//
|
|
|
|
// tweakPub := basePoint + sha256(commitPoint || basePoint) * G
|
|
|
|
// := G*k + sha256(commitPoint || basePoint)*G
|
|
|
|
// := G*(k + sha256(commitPoint || basePoint)
|
|
|
|
//
|
|
|
|
// Therefore, if a party possess the value k, the private key of the base
|
|
|
|
// point, then they are able to derive the private key by computing: compute
|
|
|
|
// the proper private key for the revokeKey by computing:
|
|
|
|
//
|
|
|
|
// revokePriv := k + sha256(commitPoint || basePoint) mod N
|
|
|
|
//
|
|
|
|
// Where N is the order of the sub-group.
|
|
|
|
//
|
|
|
|
// The rational for tweaking all public keys used within the commitment
|
|
|
|
// contracts are to ensure that all keys are properly delinearized to avoid any
|
|
|
|
// funny business when jointly collaborating to compute public and private
|
|
|
|
// keys. Additionally, the use of the per commitment point ensures that each
|
|
|
|
// commitment state houses a unique set of keys which is useful when creating
|
|
|
|
// blinded channel outsourcing protocols.
|
|
|
|
//
|
|
|
|
// TODO(roasbeef): should be using double-scalar mult here
|
|
|
|
func TweakPubKey(basePoint, commitPoint *btcec.PublicKey) *btcec.PublicKey {
|
|
|
|
tweakBytes := SingleTweakBytes(commitPoint, basePoint)
|
|
|
|
tweakX, tweakY := btcec.S256().ScalarBaseMult(tweakBytes)
|
|
|
|
|
|
|
|
// TODO(roasbeef): check that both passed on curve?
|
|
|
|
|
|
|
|
x, y := btcec.S256().Add(basePoint.X, basePoint.Y, tweakX, tweakY)
|
|
|
|
|
|
|
|
return &btcec.PublicKey{
|
|
|
|
X: x,
|
|
|
|
Y: y,
|
|
|
|
Curve: btcec.S256(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TweakPrivKek tweaks the private key of a public base point given a per
|
|
|
|
// commitment point. The per commitment secret is the revealed revocation
|
|
|
|
// secret for the commitment state in question. This private key will only need
|
|
|
|
// to be generated in the case that a channel counter party broadcasts a
|
|
|
|
// revoked state. Precisely, the following operation is used to derive a
|
|
|
|
// tweaked private key:
|
|
|
|
//
|
|
|
|
// * tweakPriv := basePriv + sha256(commitment || basePub) mod N
|
|
|
|
//
|
|
|
|
// Where N is the order of the sub-group.
|
|
|
|
func TweakPrivKey(basePriv *btcec.PrivateKey, commitTweak []byte) *btcec.PrivateKey {
|
|
|
|
// tweakInt := sha256(commitPoint || basePub)
|
|
|
|
tweakInt := new(big.Int).SetBytes(commitTweak)
|
|
|
|
|
|
|
|
tweakInt = tweakInt.Add(tweakInt, basePriv.D)
|
|
|
|
tweakInt = tweakInt.Mod(tweakInt, btcec.S256().N)
|
|
|
|
|
|
|
|
tweakPriv, _ := btcec.PrivKeyFromBytes(btcec.S256(), tweakInt.Bytes())
|
|
|
|
return tweakPriv
|
|
|
|
}
|
|
|
|
|
2016-08-13 00:37:35 +02:00
|
|
|
// DeriveRevocationPubkey derives the revocation public key given the
|
2017-01-13 06:01:50 +01:00
|
|
|
// counterparty's commitment key, and revocation preimage derived via a
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// pseudo-random-function. In the event that we (for some reason) broadcast a
|
|
|
|
// revoked commitment transaction, then if the other party knows the revocation
|
2017-01-13 06:01:50 +01:00
|
|
|
// preimage, then they'll be able to derive the corresponding private key to
|
2016-11-15 03:34:59 +01:00
|
|
|
// this private key by exploiting the homomorphism in the elliptic curve group:
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
|
|
|
|
//
|
|
|
|
// The derivation is performed as follows:
|
|
|
|
//
|
2017-07-30 03:00:23 +02:00
|
|
|
// revokeKey := revokeBase * sha256(revocationBase || commitPoint) +
|
|
|
|
// commitPoint * sha256(commitPoint || revocationBase)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
2017-07-30 03:00:23 +02:00
|
|
|
// := G*(revokeBasePriv * sha256(revocationBase || commitPoint)) +
|
|
|
|
// G*(commitSecret * sha256(commitPoint || revocationBase))
|
|
|
|
//
|
|
|
|
// := G*(revokeBasePriv * sha256(revocationBase || commitPoint) +
|
|
|
|
// commitSecret * sha256(commitPoint || revocationBase))
|
|
|
|
//
|
|
|
|
// Therefore, once we divulge the revocation secret, the remote peer is able to
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// compute the proper private key for the revokeKey by computing:
|
2017-07-30 03:00:23 +02:00
|
|
|
//
|
|
|
|
// revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
|
|
|
|
// (commitSecret * sha256(commitPoint || revocationBase)) mod N
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// Where N is the order of the sub-group.
|
2017-07-30 03:00:23 +02:00
|
|
|
func DeriveRevocationPubkey(revokeBase, commitPoint *btcec.PublicKey) *btcec.PublicKey {
|
|
|
|
|
|
|
|
// R = revokeBase * sha256(revocationBase || commitPoint)
|
|
|
|
revokeTweakBytes := SingleTweakBytes(revokeBase, commitPoint)
|
|
|
|
rX, rY := btcec.S256().ScalarMult(revokeBase.X, revokeBase.Y,
|
|
|
|
revokeTweakBytes)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:00:23 +02:00
|
|
|
// C = commitPoint * sha256(commitPoint || revocationBase)
|
|
|
|
commitTweakBytes := SingleTweakBytes(commitPoint, revokeBase)
|
|
|
|
cX, cY := btcec.S256().ScalarMult(commitPoint.X, commitPoint.Y,
|
|
|
|
commitTweakBytes)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
|
|
|
// Now that we have the revocation point, we add this to their commitment
|
|
|
|
// public key in order to obtain the revocation public key.
|
2017-07-30 03:00:23 +02:00
|
|
|
//
|
|
|
|
// P = R + C
|
|
|
|
revX, revY := btcec.S256().Add(rX, rY, cX, cY)
|
|
|
|
return &btcec.PublicKey{
|
|
|
|
X: revX,
|
|
|
|
Y: revY,
|
|
|
|
Curve: btcec.S256(),
|
|
|
|
}
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
}
|
|
|
|
|
2016-08-13 00:37:35 +02:00
|
|
|
// DeriveRevocationPrivKey derives the revocation private key given a node's
|
2017-01-13 06:01:50 +01:00
|
|
|
// commitment private key, and the preimage to a previously seen revocation
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
// hash. Using this derived private key, a node is able to claim the output
|
|
|
|
// within the commitment transaction of a node in the case that they broadcast
|
|
|
|
// a previously revoked commitment transaction.
|
|
|
|
//
|
|
|
|
// The private key is derived as follwos:
|
2017-07-30 03:00:23 +02:00
|
|
|
// revokePriv := (revokeBasePriv * sha256(revocationBase || commitPoint)) +
|
|
|
|
// (commitSecret * sha256(commitPoint || revocationBase)) mod N
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// Where N is the order of the sub-group.
|
2017-07-30 03:00:23 +02:00
|
|
|
func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
|
|
|
|
commitSecret *btcec.PrivateKey) *btcec.PrivateKey {
|
|
|
|
|
|
|
|
// r = sha256(revokeBasePub || commitPoint)
|
|
|
|
revokeTweakBytes := SingleTweakBytes(revokeBasePriv.PubKey(),
|
|
|
|
commitSecret.PubKey())
|
|
|
|
revokeTweakInt := new(big.Int).SetBytes(revokeTweakBytes)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:00:23 +02:00
|
|
|
// c = sha256(commitPoint || revokeBasePub)
|
|
|
|
commitTweakBytes := SingleTweakBytes(commitSecret.PubKey(),
|
|
|
|
revokeBasePriv.PubKey())
|
|
|
|
commitTweakInt := new(big.Int).SetBytes(commitTweakBytes)
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
|
2017-07-30 03:00:23 +02:00
|
|
|
// Finally to derive the revocation secret key we'll perform the
|
|
|
|
// following operation:
|
|
|
|
//
|
|
|
|
// k = (revocationPriv * r) + (commitSecret * c) mod N
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
//
|
|
|
|
// This works since:
|
2017-07-30 03:00:23 +02:00
|
|
|
// P = (G*a)*b + (G*c)*d
|
|
|
|
// P = G*(a*b) + G*(c*d)
|
|
|
|
// P = G*(a*b + c*d)
|
|
|
|
revokeHalfPriv := revokeTweakInt.Mul(revokeTweakInt, revokeBasePriv.D)
|
|
|
|
commitHalfPriv := commitTweakInt.Mul(commitTweakInt, commitSecret.D)
|
|
|
|
|
|
|
|
revocationPriv := revokeHalfPriv.Add(revokeHalfPriv, commitHalfPriv)
|
|
|
|
revocationPriv = revocationPriv.Mod(revocationPriv, btcec.S256().N)
|
|
|
|
|
|
|
|
priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), revocationPriv.Bytes())
|
|
|
|
return priv
|
lnwallet: update HTLC+commitment scripts
This commit updates the previous HTLC and commitment scripts to their
current latest evolution.
The HTLC scripts have been optimized for space savings, the
functionality itself has remained relatively unchanged. A trade off was
made to add additional bytes into the sigScript in order to avoid
extraneous CHECKSIG’s. The rationale is that an extra 1-2 bytes in the
sigScript to guide execution, are worthwhile since they’re in the
witness, and witness data may be pruned in the near future.
The primary change is within the commitment transaction itself. Instead
of using revocation hashes, we now use signature based revocation. This
saves space in the Script, and optimizes away an extra hashing
operation. Elkrem/shachain is still used but, we now use the pre-images
to homomorphically derive a public key which the other party will be
able to sign with, once we disclose the pre-image itself.
Finally, we have switched to using SHA-256 everywhere uniformly for
both revocation hashes, and payment hashes. The rationale is that the
output of ripemd160 is too small for modern security margins, and that
other coins/chains are more likely to have SHA-256 implemented, than
ripemd160.
A set of tests has also been included which contain (mostly) exhaustive
tests of all possible redemption paths for both commitment and HTLC.
2016-06-27 20:33:59 +02:00
|
|
|
}
|
2016-06-30 21:08:27 +02:00
|
|
|
|
2017-05-02 01:25:32 +02:00
|
|
|
// DeriveRevocationRoot derives an root unique to a channel given the
|
2017-07-30 02:55:05 +02:00
|
|
|
// derivation root, and the blockhash that the funding process began at and the
|
|
|
|
// remote node's identity public key. The seed is derived using the HKDF[1][2]
|
|
|
|
// instantiated with sha-256. With this schema, once we know the block hash of
|
|
|
|
// the funding transaction, and who we funded the channel with, we can
|
|
|
|
// reconstruct all of our revocation state.
|
2016-06-30 21:08:27 +02:00
|
|
|
//
|
|
|
|
// [1]: https://eprint.iacr.org/2010/264.pdf
|
|
|
|
// [2]: https://tools.ietf.org/html/rfc5869
|
2017-05-02 01:25:32 +02:00
|
|
|
func DeriveRevocationRoot(derivationRoot *btcec.PrivateKey,
|
2017-07-30 02:55:05 +02:00
|
|
|
blockSalt chainhash.Hash, nodePubKey *btcec.PublicKey) chainhash.Hash {
|
2016-06-30 21:08:27 +02:00
|
|
|
|
2016-12-14 15:01:48 +01:00
|
|
|
secret := derivationRoot.Serialize()
|
2017-07-30 02:55:05 +02:00
|
|
|
salt := blockSalt[:]
|
|
|
|
info := nodePubKey.SerializeCompressed()
|
2016-06-30 21:08:27 +02:00
|
|
|
|
2016-12-14 15:01:48 +01:00
|
|
|
seedReader := hkdf.New(sha256.New, secret, salt, info)
|
2016-06-30 21:08:27 +02:00
|
|
|
|
|
|
|
// It's safe to ignore the error her as we know for sure that we won't
|
|
|
|
// be draining the HKDF past its available entropy horizon.
|
|
|
|
// TODO(roasbeef): revisit...
|
2016-12-14 15:01:48 +01:00
|
|
|
var root chainhash.Hash
|
|
|
|
seedReader.Read(root[:])
|
2016-06-30 21:08:27 +02:00
|
|
|
|
2017-07-30 02:55:05 +02:00
|
|
|
return root
|
2016-11-15 03:34:59 +01:00
|
|
|
}
|
|
|
|
|
2016-11-16 21:54:27 +01:00
|
|
|
// SetStateNumHint encodes the current state number within the passed
|
2017-07-30 03:00:23 +02:00
|
|
|
// commitment transaction by re-purposing the locktime and sequence fields in
|
|
|
|
// the commitment transaction to encode the obfuscated state number. The state
|
|
|
|
// number is encoded using 48 bits. The lower 24 bits of the lock time are the
|
|
|
|
// lower 24 bits of the obfuscated state number and the lower 24 bits of the
|
|
|
|
// sequence field are the higher 24 bits. Finally before encoding, the
|
|
|
|
// obfuscater is XOR'd against the state number in order to hide the exact
|
|
|
|
// state number from the PoV of outside parties.
|
2017-01-04 16:15:50 +01:00
|
|
|
func SetStateNumHint(commitTx *wire.MsgTx, stateNum uint64,
|
2016-11-15 03:34:59 +01:00
|
|
|
obsfucator [StateHintSize]byte) error {
|
|
|
|
|
|
|
|
// With the current schema we are only able able to encode state num
|
2017-01-04 16:15:50 +01:00
|
|
|
// hints up to 2^48. Therefore if the passed height is greater than our
|
2016-11-15 03:34:59 +01:00
|
|
|
// state hint ceiling, then exit early.
|
2017-01-09 14:58:58 +01:00
|
|
|
if stateNum > maxStateHint {
|
2016-11-15 03:34:59 +01:00
|
|
|
return fmt.Errorf("unable to encode state, %v is greater "+
|
|
|
|
"state num that max of %v", stateNum, maxStateHint)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(commitTx.TxIn) != 1 {
|
|
|
|
return fmt.Errorf("commitment tx must have exactly 1 input, "+
|
|
|
|
"instead has %v", len(commitTx.TxIn))
|
|
|
|
}
|
|
|
|
|
2017-01-04 16:15:50 +01:00
|
|
|
// Convert the obfuscator into a uint64, then XOR that against the
|
2016-11-15 03:34:59 +01:00
|
|
|
// targeted height in order to obfuscate the state number of the
|
|
|
|
// commitment transaction in the case that either commitment
|
|
|
|
// transaction is broadcast directly on chain.
|
2017-01-04 16:15:50 +01:00
|
|
|
var obfs [8]byte
|
|
|
|
copy(obfs[2:], obsfucator[:])
|
|
|
|
xorInt := binary.BigEndian.Uint64(obfs[:])
|
|
|
|
|
2016-11-15 03:34:59 +01:00
|
|
|
stateNum = stateNum ^ xorInt
|
|
|
|
|
|
|
|
// Set the height bit of the sequence number in order to disable any
|
|
|
|
// sequence locks semantics.
|
2017-01-04 16:15:50 +01:00
|
|
|
commitTx.TxIn[0].Sequence = uint32(stateNum>>24) | wire.SequenceLockTimeDisabled
|
2017-01-13 15:29:56 +01:00
|
|
|
commitTx.LockTime = uint32(stateNum&0xFFFFFF) | TimelockShift
|
2016-11-15 03:34:59 +01:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-11-16 21:54:27 +01:00
|
|
|
// GetStateNumHint recovers the current state number given a commitment
|
2016-11-15 03:34:59 +01:00
|
|
|
// transaction which has previously had the state number encoded within it via
|
|
|
|
// setStateNumHint and a shared obsfucator.
|
|
|
|
//
|
|
|
|
// See setStateNumHint for further details w.r.t exactly how the state-hints
|
|
|
|
// are encoded.
|
2017-01-04 16:15:50 +01:00
|
|
|
func GetStateNumHint(commitTx *wire.MsgTx, obsfucator [StateHintSize]byte) uint64 {
|
|
|
|
// Convert the obfuscater into a uint64, this will be used to
|
2016-11-15 03:34:59 +01:00
|
|
|
// de-obfuscate the final recovered state number.
|
2017-01-04 16:15:50 +01:00
|
|
|
var obfs [8]byte
|
|
|
|
copy(obfs[2:], obsfucator[:])
|
|
|
|
xorInt := binary.BigEndian.Uint64(obfs[:])
|
|
|
|
|
|
|
|
// Retrieve the state hint from the sequence number and locktime
|
|
|
|
// of the transaction.
|
|
|
|
stateNumXor := uint64(commitTx.TxIn[0].Sequence&0xFFFFFF) << 24
|
|
|
|
stateNumXor |= uint64(commitTx.LockTime & 0xFFFFFF)
|
2016-11-15 03:34:59 +01:00
|
|
|
|
|
|
|
// Finally, to obtain the final state number, we XOR by the obfuscater
|
|
|
|
// value to de-obfuscate the state number.
|
|
|
|
return stateNumXor ^ xorInt
|
|
|
|
}
|
2017-07-30 03:00:23 +02:00
|
|
|
|
|
|
|
// ComputeCommitmentPoint generates a commitment point given a commitment
|
|
|
|
// secret. The commitment point for each state is used to randomize each key in
|
|
|
|
// the key-ring and also to used as a tweak to derive new public+private keys
|
|
|
|
// for the state.
|
|
|
|
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
|
|
|
|
x, y := btcec.S256().ScalarBaseMult(commitSecret)
|
|
|
|
|
|
|
|
return &btcec.PublicKey{
|
|
|
|
X: x,
|
|
|
|
Y: y,
|
|
|
|
Curve: btcec.S256(),
|
|
|
|
}
|
|
|
|
}
|