Files
specs/02.md
2023-03-07 16:09:27 +01:00

4.6 KiB

BDS-02

Channel Addresses

draft mandatory author:brqgoo

This BDS defines a non-interactive channel opening scheme.

Rationale

Today, funding outpoints must be known before establishing a new channel to craft a refund from the 2-of-2 multisig. This has three main drawbacks:

On-chain footprint

Cannot allow batch openings, consuming more on-chain footprint. A third party (i.e. on-ramp exchange) cannot open a channel for two other parties (between the user and LSP), among other outputs. Note that Vortex enables batch openings as a side result but requires interactivity pre-channel formation.

On-chain privacy

In comparison to batch openings, regular channel establishments are less privacy-preserving. Funding transaction consumes one or more inputs, a channel output, and a probabilistic change. It might have two changes if dual-funded. On-chain observers MAY have an idea whether this might be a funding transaction.

Convenience

Inconvenient for onboarding new users who have no UTXO possession in the beginning.

Specification

This BDS proposes a non-interactive channel opening scheme called channel addresses. Channel addresses make it possible to craft on-chain bitcoin addresses such that when funded, becomes a payment channel between to_self and to_remote, where the channel funds are initially kept on to_self side.

The specification first defines how to derive child public keys from a parent npub using plain tweaking. Then passing derived child keys to key aggregation algorithm (KeyAgg) to obtain the aggregate public key, and finally applying an x-only tweak to 2-of-2 aggregate public key to add a single-leaf script path. The added script path enforces a non-interactive refund closure that permits to_self to spend funds after a relative locktime, similar to pre-segwit timeout channel design.

Adding a non-interactive refund closure to a 2-of-2 multisig removes the need to craft a refund transaction in advance of funding a channel output. to_self can exit from the script path after the expiry if the to_remote happens to be non-collaborative in exchanging signatures for a refund.

Ultimately, it's to_remote responsibility to close the channel shortly before channel expiry. While this design consume more on-chain footprint over time than regular channel formations, its anticipated to_self users to mostly receive funds over silent swaps and rarely through channel addresses.

Crafting Channel Addresses

The number of channel addresses u: 232.

Child Key Derivation

  • The nostr parent secret key nsec: a 32-byte array.
  • The nostr parent public key npub: cbytes(int(nsec)⋅G).
  • The tweak derivation secret ds: a 32-byte array.
  • Let ds = hashBDS-02/dersec(nsec).
  • For i = 1 .. u:
    • The BDS-02 child secret key ski.
    • The BDS-02 child public key pki.
    • pki BIP-340 tweak ti : 32-byte array.
    • Let ti = hashBDS-02/tweak(ds || bytes(32, i)).
    • Let pki = cbytes(npub + int(ti)⋅G).
    • Let ski = bytes(32, (int(nsec) + int(ti )) mod n).

Key Aggregation

  • For i = 1 .. u:
    • The to_self : 32-byte x-only user child public key.
    • The to_remote : 32-byte x-only well-known LSP public key.
    • The keygen_ctx : MuSig2 keygen context containing the aggregate key.
    • Let to_self = cbytes(pki).
    • Let to_remote = cbytes(bytes(33, 0x025de7cd8fd3a0a38f1cab124defd4c3043203c3f2b66328484e321d3ede5f84f6)).
    • Let keygen_ctxi = KeyAgg([to_self, to_remote]).
    • Let Qi, gacci, and tacci = keygen_ctxi.

Adding Refund Closure

  • For i = 1 .. u:
    • The ex : a 2-byte minimally encoded channel expiry as relative locktime.
    • The ts : a 39-byte raw tapscript for a non-interactive refund closure.
    • The addr : Expiring channel address.
    • Let ex = CScriptNum(26280).
    • Let ts = <ex> OP_CHECKSEQUENCEVERIFY OP_DROP <to_self> OP_CHECKSIG.
    • Let tshash = hashTapLeaf(0xc0 || 0x27 || ts).
    • Let tstweak = hashTapTweak(xbytes(Qi) || tshash).
    • Let keygen_ctx' = ApplyTweak(Qi, tstweak, true).
    • Let Q'i, gacc'i, and tacc'i = keygen_ctx'i.
    • Let addr = Bech32m(bytes(34, 0x5120 || xbytes(Q'i))).