Good morning list,

As usual, I am spamming the list for my amusement.

Thus, I would like to thank you for your tolerance and continued attention.

----

We have identified two requirements:

1.  We must identify which participant initiated the unilateral close onchain.
    We do so that if later, we find that the unilateral close was to an older 
state, we can punish the participant that initiated the unilateral close.
2.  We must identify that a unilateral close was, in fact, to an older state.

Thus, I will counterpropose a construction similar to that originally proposed 
here, but with the weaknesses fixed and key details filled in.
(while part of it is similar to the Decker-Russell-Osuntokun "eltoo", it is 
different enough that I would not suggest calling it "eltoo-penalty")

----

On initiation, Alice, Bob, and Charlie indicate:

* Alice/Bob/Charlie "fingerprint" hash/preimage.
  Alice/Bob/Charlie publish the fingerprint hashes, but keep the fingerprint 
preimages secret.
* Alice/Bob/Charlie "normal" pubkey.
* Alice/Bob/Charlie "lawyer" pubkey.
* All participants indicate a `delay`, a number of blocks.
  Funds may be locked, in worst case, up to `2 * delay`.

We also introduce a "common" key whose private key is known to all participants.
For example, we can use a key whose private key is `SHA256("ZmnSCPxj is a human 
being and not any kind of AI")` as a consensus-accepted fact.

We have the below transactions:

* Funding transaction
  * inputs: unspecified
  * outputs:
    * change output(s): unspecified
    * funding output:
      * Internal Taproot Key: `P = MuSig(Alice normal pubkey, Bob normal 
pubkey, Charlie normal pubkey)`
      * Scripts:
        * `OP_1 OP_CHECKSIGVERIFY OP_HASH160 <Alice fingerprint hash> 
OP_EQUALVERIFY`
        * `OP_1 OP_CHECKSIGVERIFY OP_HASH160 <Bob fingerprint hash> 
OP_EQUALVERIFY`
        * `OP_1 OP_CHECKSIGVERIFY OP_HASH160 <Charlie fingerprint> 
OP_EQUALVERIFY`

* Update Transaction
  * comment: this transaction initiates a unilateral close attempt.
  * comment: Updates have a "hidden" `n`, which is an "update" number 
incrementing from 0.
    This number could be encoded as `nLockTime` by using `500e6 + n`, but in 
principle does not need to be encoded there (we could use the current encoding 
in Poon-Dryja, which is encrypted so that normal unilateral closes do not 
reveal how many updates occurred).
  * Update transaction might have other inputs/outputs used to pay for onchain 
fees.
  * input:
    * Funding transaction output
    * witness: one of the following, depending on which participant initiated 
the unilateral close:
      * `<Alice fingerprint preimage> sign(MuSig(A normal, B normal, C normal), 
SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_SINGLE)`
      * `<Bob fingerprint preimage> sign(MuSig(A normal, B normal, C normal), 
SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_SINGLE)`
      * `<Charlie fingerprint preimage> sign(MuSig(A normal, B normal, C 
normal), SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_SINGLE)`
    * comment: which witness script appears onchain depends on which 
participant initiated the unilateral close.
  * output:
    * Internal Taproot Key: `MuSig(A normal, B normal, C normal)`
    * Scripts:
      * `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP <MuSig(A normal, B normal, C 
normal)> OP_CHECKSIG`
        * This is the "normal" unilateral path where the participant did not 
steal any funds.
      * `<500e6 + n + 1> OP_CHECKLOCKTIMEVERIFY OP_DROP <MuSig(A lawyer, B 
lawyer, C lawyer)> OP_CHECKSIG`
        * This is the "litigation" path where the participant is proven to have 
stolen funds by showing a litigation transaction with later `n` than the update 
transaction.

* Friendly Settlement Transaction
  * comment: This transaction completes a unilateral close attempt and 
publishes all contracts transported in the channel without revocability 
branches.
  * `nSequence`: `<delay>`
  * input:
    * Update transaction output
    * witness: `sign(MuSig(A normal, B normal, C normal), 
SIGHASH_ANYPREVOUTANYSCRIPT)`
  * outputs: unencumbered outputs for this state.

* Litigation Transaction
  * comment: The appearance of this transaction onchain is taken as proof that 
the unilateral close attempt is definitely a theft attempt.
    It can only be broadcast and confirmed if and only if the unilateral close 
Update Transaction has an `n` that is less than the latest agreed `n`.
  * comment: A Litigation Transaction can be spent by another Litigation 
Transaction with higher `n`.
    The intent is to force the current state onchain, in order to punish the 
thief using the *latest* state instead of punishing from old state.
  * `nLockTime`: `500e6 + n`, where `n` is the update index for this Litigation 
Transaction.
    * comment: a Litigation Transaction with `n` cannot spend an Update 
Transaction of same `n`, only `n - 1` or less.
  * input:
    * Update transaction output *OR* another Litigation Transaction output; 
Update/Litigation tx has `n` less than this Litigation transaction.
    * witness: `sign(MuSig(A lawyer, B lawyer, C lawyer), 
SIGHASH_ANYPREVOUTANYSCRIPT | SIGHASH_SINGLE)`
  * output:
    * Internal Taproot Key: `MuSig(A lawyer, B lawyer, C lawyer)`
    * scripts:
      * `<500e6 + n + 1> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_1 OP_CHECKSIG`
        * comment: This allows a Litigation Transaction with later `nLockTime` 
to spend this Litigation Transaction.
      * `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP <500e6 + n> 
OP_CHECKLOCKTIMEVERIFY OP_DROP OP_1 OP_CHECKSIG`
        * comment: This is the "Hostile Settlement" path that allows revocation 
of outputs owned by the participant that initiated the unilateral close.

* Hostile Settlement Transaction
  * `nLockTime`: `500e6 + n`
  * input:
    * Litigation Transaction output
    * witness: `sign(MuSig(A lawyer, B lawyer, C lawyer), 
SIGHASH_ANYPREVOUTANYSCRIPT)`
  * outputs:
    * Depending on type of contract, outputs are revocable:
      * Single-ownership contract (example below is Alice-owned)
        * Taproot Internal Key: `P = NUMS point` (cannot be spent via 
non-Taproot path)
        * scripts:
          * `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP <A lawyer> OP_CHECKSIG`
            * comment: This lets Alice recover its funds if it is not the thief.
          * `OP_0 OP_CHECKSEQUENCEVERIFY OP_DROP OP_HASH160 <Alice fingerprint 
hash> OP_EQUALVERIFY <common key> OP_CHECKSIG`
            * comment: Alice fingerprint preimage is published if Alice is the 
one who published the old Update Transaction.
              Any participant can take that preimage and re-publish it here.
            * comment: the `0 OP_CHECKSEQUENCEVERIFY` ensures the spending 
script has RBF enabled.
            * comment: we use the common key, and the requirement to provide 
the Alice fingerprint preimage, *and* the requirement to enable RBF, to force 
the output to be revoked to miners as fees: when the entire output is given as 
fee, no higher RBF is possible.
              * comment: outputs may become too tiny to care about if we split 
up a tiny reserve between dozens of honest participants.
                But the important point is to punish the thief, not award the 
honest participants.
              * comment: further, since the Litigation Transaction *should* 
make valid the latest Hostile Settlement, the outputs of the honest 
participants are at the latest state, already, so they cannot lose funds by 
having the thief-owned outputs be revoked in favor of miners.
      * Dual-ownership contract (example below is an HTLC from Bob to Charlie)
        * Taproot Internal Key: `P = NUMS point`
        * scripts:
          * `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP <locktime> 
OP_CHECKLOCKTIMEVERIFY OP_DROP <B lawyer> OP_CHECKSIG`
            * comment: Timelock branch, Bob reclaims money.
          * `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP OP_HASH160 <hash> 
OP_EQUALVERIFY <C lawyer> OP_CHECKSIG`
            * comment: Hashlock branch, Charlie claims funds in exchange for 
publishing payment preimage.
          * `OP_HASH160 <Bob fingerprint hash> OP_EQUALVERIFY <C lawyer> 
OP_CHECKSIG`
            * comment: Revocation branch, Bob attempted to steal, so Charlie 
gets the money outright.
          * `OP_HASH160 <Charlie fingerprint hash> OP_EQUALVERIFY <B lawyer> 
OP_CHECKSIG`
            * comment: Revocation branch, Charlie attempted to steal, so Bob 
gets the money outright.
        * Any two-participant contract can be made revocable by the same 
pattern:
          * Use a NUMS point for taproot internal key.
          * Give every branch explicitly as a branch in the Taproot MAST; 
prepend an additional `<delay> OP_CHECKSEQUENCEVERIFY OP_DROP`.
          * Add branches for revocation, where proof that one side attempted to 
steal allows the other side to control the coin immediately.
        * Sub-channels will need to use `SIGHASH_ANYPREVOUTANYSCRIPT`, so that 
signatures that can spend from an output of the Friendly Settlement can also 
spend from an output of the Hostile Settlement (once the additional 
encumberance has been passed).

So, here are some changes to the original proposal:

* We use a hash/preimage challenge to identify *who* attempted to steal.
  * The "revocation key" is the same as the "fingerprint".
    It is safe to publish the revocation key if you publish only the latest 
Update Transaction, as the latest Update Transaction cannot enable any 
Litigation Transaction.
* Single-ownership outputs of the current state are encumbered by a 
revocability clause that revokes in favor of miners.
* Dual-ownership outputs of the current state are encumbered by a revocability 
clause that revokes in favor of the non-thief participant if one of the 
participants is the thief.
* Outputs with more than two owners are not supported by this construction.

It was not very clear from the original proposal, but the Litigation 
Transaction path ensures we can go to the latest state, and the Hostile 
Settlement transaction represents the latest state, plus allowing revocability 
of outputs in that state.
This behavior allows us to perform our punishments based on the latest state, 
compared to Poon-Dryja which punishes based on the old published state (which 
is simpler since it always just rewards the entire channel funds to the honest 
party).

The Friendly Settlement transaction does not allow any revocability, but can 
only be published if no Litigation Transaction has been published.

Regards,
ZmnSCPxj
_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to