Ed25519 Signed Payload Signer for Transaction Signature Disclosure for Payment Channels

265 views
Skip to first unread message

Leigh McCulloch

unread,
Jul 15, 2021, 3:54:16 PM7/15/21
to Stellar Developers
Hi all,

I've posted CAP-40 that proposes a new signer that, alongside the extraSigners precondition proposed in CAP-21, allows participants in multi-party contracts to share a batch of transactions for signing with a guarantee that if one transaction is signed, authorized, and submitted that information is revealed that allows all other transactions in the batch to be authorized.

This proposal is relevant to payment channels, and is the result of experimenting with the payment channel designs that CAP-21 makes possible.

In the bi-directional payment channel designs described in CAP-21 participants must exchange signatures for two transactions in reverse order and one at a time to ensure that neither participant could execute a subset of the transactions and refuse to sign teh remainder. This multi-step signing process increases the complexity of all implementations, and makes some implementations impractical.

This proposal will allow participants in a payment channel to exchange signatures for a set of transactions in a single-step.

This new signer probably has other applications as well wherever the HASH_X signer is currently used.

The proposal goes into greater detail about how the payment channels in CAP-21 are changed as a result and the benefits we get:

Feedback appreciated.

Cheers,
Leigh

Nicolas Barry

unread,
Jul 15, 2021, 9:02:49 PM7/15/21
to Leigh McCulloch, Stellar Developers

Nicolas


--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/stellar-dev/76a2c970-04f2-4481-914b-ab762d8b1093n%40googlegroups.com.

Leigh McCulloch

unread,
Jul 16, 2021, 1:52:47 AM7/16/21
to Stellar Developers
Thanks for surfacing that proposal. I think a merkle tree signer for signing a large number of transactions is interesting. That concept has been discussed more recently on the mailing list here too. 

Issue #92 is brief so I could be missing something, but there still has to be a way to require a specific merkle tree signer root for the transaction batch so that a participant doesn't use their regular signer. The extraSigners is inside the transaction signature payload so it can't introduce a cyclic dependency and a transaction can't include itself in the merkle tree. This means there wouldn't be one merkle tree signer for the batch, but one per transaction that contained all subsequent transactions.

I think it would work but it has different trade offs:

- A signed payload is rather simple to create and verify using primitives available in most standard libraries, both for core and for contract participants. A merkle tree signer requires merkle tree building and path verification in every implementation of the contract, not just core.
- A signed payload adds one 64 bytes to the extraSigners precondition of the first transaction for every transaction after the first, e.g. for three transactions the first has two extraSigners, the second and third have none. A merkle tree signer would add 32 bytes to every transaction in the batch, except maybe the last. The storage cost here is nominally higher for the signed payload, but building and verification are a higher cost may be significant for the merkle tree.
- A signed payload signature adds 32 bytes per transaction disclosed to the first transaction. A merkle tree signer would add 32 bytes to every transaction, maybe except the last, for any number of transactions. The cost here is equivalent.
- A signed payload signature probably won't affect utilization with a limited number of extraSigners and so I think we can defer changes to fees until a day where more than two extraSigners are required. Nicolas mentioned here previously a merkle tree signer requires a redesign of fees.
- A signed payload is very generic and may have other applications outside transaction hashes and doesn't need to contain any logic specific to transaction hashes. A merkle tree signer could also have other applications, but would require logic specific to transaction hashes.

I think the trade offs of the simpler signed payload are preferred, and both signers can coexist if we discover a need for merkle tree signers, but I'm interested to hear what you and others think.

Leigh McCulloch

unread,
Jul 27, 2021, 1:04:52 PM7/27/21
to Stellar Developers
David pointed out offline that we need a new strkey for the signer introduced by CAP-40, and rather than introduce a new SEP for this and each future strkey we should refactor SEP-23 such that it becomes a strkey specification.

I've opened two changes to SEP-23:

The first refactors SEP-23 to change it from being a proposal for Muxed Account strkeys to being a specification for strkeys. This is intended for merging now and is not dependent on CAP-40 being accepted since it is beneficial for us to have one place for strkey specifications.

The second adds a new strkey for the signer that is introduced by CAP-40. The is intended for merging if CAP-40 is accepted and implemented.

Leigh

Leigh McCulloch

unread,
Jul 29, 2021, 12:34:10 AM7/29/21
to Stellar Developers
The design rationale section has been expanded to include examples of how the change affects the message exchange between parties in a payment channel. The number of messages exchanged change from three messages to at most two messages. In the case of simple bidirectional payment channels where a single party is the beneficiary of each payment the number of messages exchanged can be reduced to one message. See the examples at:

Eric Saunders

unread,
Jul 29, 2021, 4:53:59 PM7/29/21
to Leigh McCulloch, Stellar Developers
1) Why was XOR selected instead of e.g. sha256? XOR has larger collision potential. Also, For payload < 4 bytes, is it ok that xor(0) reveals the key bytes?

2) From the CAP: If the payload has a length less than 4 bytes, then 1 to 3 zero bytes are appended to the payload such that it has a length of 4 bytes, for calculating the hint.

Technically it can also be 0 bytes long and a pubkey XORed with all 0s will be the same.

Eric

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.

Leigh McCulloch

unread,
Jul 29, 2021, 6:56:29 PM7/29/21
to Stellar Developers
>Why was XOR selected instead of e.g. sha256? XOR has larger collision potential.

An initial version of the proposal used sha256, however it was pointed out that it was rather expensive to calculate the hint compared to other signer's hints. Given the hint is only 4 bytes it has a large collision potential no matter what approach we take. The most likely collision to arise is with a non-payload signature for the current transaction using the same ed25519 public key. With the xor this should only occur if the payload is 0s, which is not a sensible use of the payload.

>For payload < 4 bytes, is it ok that xor(0) reveals the key bytes?

The public key is already public because it is stored either in the account signers or in the extraSigner precondition on the tx. In both cases the payload is stored alongside it, and the signature hint is derived from those two things.

>If the payload has a length less than 4 bytes, then 1 to 3 zero bytes are appended to the payload such that it has a length of 4 bytes, for calculating the hint.

Thanks for highlighting this inconsistency. I updated the proposal in CAP-40@ad1a3ed.

Leigh McCulloch

unread,
Feb 15, 2022, 2:43:52 PM2/15/22
to Stellar Developers
I've made a change to CAP-40 expanding the 32 byte maximum payload length to 64 bytes.

This change came out of a conversation with David, where we were attempting to make CAP-40 usable in cross-chain applications. As noted in the change is not practical when the cross-chain interaction requires signing a transaction for another chain because most chains do not hash the ed25519 payload before signing, which would require the payload of the signer to contain the full transaction on the other chain and therefore support a large maximum length that is unreasonable (e.g. 256 to 512 bytes, or greater). 

However, David noted that if we simply increase the maximum payload to 64 bytes, we allow the payload to contain any hash since most hash algorithms that are defined today that produce digests that are over 32 bytes long, do not exceed 64 bytes. While this wouldn't support signing a transaction for another chain, it would allow requiring a signature of a hash of some data that is verified by a smart contract on another chain and the change to 64 bytes makes CAP-40 compatible with a wider variety of hashing algorithms rather than only algorithms with 32 byte digests.

The change is visible in CAP-40@90b6137.

Reply all
Reply to author
Forward
0 new messages