public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Ali Sherief <ali@notatether.com>
To: bitcoin-dev@lists.linuxfoundation.org
Subject: [bitcoin-dev] A method for BIP322 signing delegation
Date: Sun, 14 Aug 2022 04:25:33 +0000	[thread overview]
Message-ID: <20220814042526.n7osmg5n7pfssauh@artanis> (raw)

[A similar message was posted in the Bitcointalk BIP322 thread.]

OK, I just figured out how to solve the delegation problem. It builds on Jeremy Rubin's transaction delegation post which I linked to a few days ago.

In BIP322, there is a [planned] provision for some person to delegate signing to another person. That means the second person can do all the signing stuff that the first person could do, and the signature is as if the first person signed it.

What this could be useful for?

- L2/Lightning Network, a channel is just 2-of-2 multisig, so a prospective channel co-creator "delegate" signing to the channel itself, by signing a UTXO inside the multisig - signing along with the other party, creating a dummy output (see below), which can be signed to prove liquidity on behalf of the channel, while keeping the channel itself anonymous.
- CoinJoin, To prove that some CoinJoin coordinator is liquid without violating its anonymity by revealing public keys, the person managing the CoinJoins delegates signing from all UTXOs to be used in the CJ, at once, delegating signing to another dummy output.
- By the same token, Mixers can prove their liquidity without revealing their UTXO set.
- Silent Payments, where the public key is not even known in the first place, the address of a silent payment can delegate signing to another dummy output which only the sender and receiver know about.

So how does this delegation work? It's very simple:

1. All UTXOs that want to delegate signing to a different party must sign a preliminary transaction of this format:
- All input/output amounts are zero.
- input 1 is an invalid input of the kind in BIP322
- the rest of the inputs are the UTXOs wanting to delegate signing to a different party, with valid signatures/witness stacks.
- there is only one output, and it is a P2WSH output with the following script:
OP_PUSH <hash-of-address-hash> OP_SWAP OP_HASH160 OP_EQUALVERIFY
- And the witness stack that will "spend" the transaction in the "to_spend" tx is simply:
<address-hash>
- Likewise, the "to_spend" tx has only one input, refering to the txid of the delegating transaction with output point 0 i.e. the UTXO <delegation-txid>:0. Outputs of "to_spend" remain the same.
-- Contrary to the use of Hash160, we are NOT hashing a public key or script. We are hashing an address hash, implying that we are using addresses.

Do you know why I said "delegating to a different party"? Because it could be a functionally different entity, just like how CEO is diffferent from LLC company even if it has only 1 employee. The "address" here represents a kind of company <but is not a smart contract> - it can represent a channel, it can represent a coinjoin, it can represent a silent payment. The channel/CJ/etc. only has to hash the decoded RIPEMD160 of an address, with another SHA256-RIPEMD160, to make an "address" that can be used to sign messages from.

This "address" aka. LLC company can even be encoded with Bech32 to make it look like a real address - obviously don't send any funds directly to that address because they will be lost - and in fact, it *should* be Bech32-encoded when transmitting the Signed Message.

A signed message has these three parts:

Message
Address
Signature

BIP322 specifies the signature is just the raw transaction format of "to_sign". Normally, the address would simply be the address you are signing from, but in the case of delegation, it is desireable for the original addresses to remain anonymous. So since an address must be filled in somewhere, the Bech32 "hash-of-address-hash" created above can be used as a P2WSH address.

Advantages of this scheme:

- The real addresses/UTXOs signing the transaction are only known to each other and whoever is managing the "to_delegate" transaction.
- Only the real signers and the person who is in charge of the P2WSH output can sign the "to_delegate" output and thus sign a message from it (note that they could be the same person).
- There can be an arbitrary number of delegations before the transaction is actually signed (the new person who is in charge of signing, i.e. has the P2WSH output of the "to_delegate" transaction can simply generate another address hash, and delegate to that "address" in another transaction, giving some other person that "address" if they want to)
- Delegated signatures can wrap Full and Full with UTXOs signing formats, so Light clients do not have to directly support those two formats, either for complexity reasons, or because they have no UTXO set.
- And crucially: **There is no on-chain transaction, so the delegation is private and cannot be traced back by the public**.

And there are virtually no disadvantages to this.

I should emphasize that you don't delegate signing to another person, you delegate signing to another party that may just be comprised by one person. I say this because the delegation does not make any new on-chain UTXOs that someone could posess, but it simply creates a hash160 of some address hash that was generated by the delegators, and the hash-of-address-hash does not necessarily have to represent a person, it can also represent a service.

FAQ:

Q: Does this utilize the Full format?
A: Yes.

Q: How to represent the delegation in a signed transaction?
A: Just encode the hash-of-address-hash in Bech32 version 0 and put it in the Address field.

Q: If the delegation is private, then how can the address-hash be known and the transaction signed?
A: The UTXO signers take a random address associated with them <could be one of their own address, could be the address of a multisig that is being used elsewhere etc.> and then make the hash160 of that address. Whoever they give this to, can sign a BIP322 transaction.

Q: How can the public verify a delegated BIP322 transaction if the address-hash is private?
A: The hash-of-address-hash is revealed in the Address, not in the Signature. BIP322 states that the signature only contains the "to_sign" transaction, which does not contain the witness stack of "to_spend" that has the hash-of-address-hash (because THAT was already spent in "to_spend") therefore the address hash is Bech32 (version 0) encoded and can be decoded to re-construct "to_spend" transaction and from there "to_sign".

Q: How to differentiate between non-delegated and delegated signatures?
A: You can't. But then again, BIP322 doesn't differentiate between "message signatures from an address" and a signature from a set of UTXOs so it wouldn't be able to identify a delegated transaction anyway.
Rather, a full-blown verification software should present a list-box or a set of radio buttons, that toggles between "Legacy", "Simple", "Full", "Full with UTXOs" and "Full with Delegation" - Each of these controls the content in the Address field - this would already be required to support validating Legacy signatures anyway, which are otherwise incompatible with the transaction-based signing (and this is the workaround BIP322 specifies to support that).

Q: What if the verifier does not have a UTXO set (light clients)?
A: Then present three toggles or radio buttons: "Legacy", "Simple", and "Delegated" - each of these options only require a single encoded address to be specified in the field, and Full, and Full With UTXOs signatures can be wrapped with a delegation to support a single address. Consequentially, these control how the signed transaction is [re]constructed for sign/verify.

CC'ing Kalle as he might be interested in this.

- Ali



             reply	other threads:[~2022-08-14  4:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-14  4:25 Ali Sherief [this message]
2022-08-16  4:38 [bitcoin-dev] A method for BIP322 signing delegation Ali Sherief
2022-08-19  6:23 Ali Sherief
2022-08-22  7:56 Ali Sherief

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220814042526.n7osmg5n7pfssauh@artanis \
    --to=ali@notatether.com \
    --cc=bitcoin-dev@lists.linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox