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_](https://github.com/bits-wallet/specs/blob/main/04.md) 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_ = ` OP_CHECKSEQUENCEVERIFY OP_DROP 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)))_.