penumbra
penumbra copied to clipboard
consider lifting `Memo` to transaction level
Is your feature request related to a problem? Please describe. Currently we have memos on a per-Output basis. They are encrypted to a shared key between the sender and the recipient.
Describe the solution you'd like
One alternative is to have a per-transaction Memo
.
Pros:
- This makes transactions smaller: instead of N memos for N outputs, we'd have just one memo, plus some overhead due to the key wrapping we would need such that the recipient associated with each output can decrypt the memo. Memo ciphertexts are 528 bytes currently.
Cons:
- If in a single transaction the user wanted to send a different memo to two outputs, this would no longer be possible. Unclear how common this is. However they could send two transactions in that case.
- In the case of multiple outputs, each recipient associated with an output learns the memo that is sent to all others in the transaction. How important is this?
Looks like there's a similar discussion over in zcash land: https://github.com/zcash/zips/issues/627
A few points to consider:
-
Having memos attached to a transaction rather than an output seems conceptually clearer: the transaction is a bundle of actions accomplishing some purpose, and the memo can describe that purpose. On the other hand, having a memo attached to each output means that we have to convey that there can be multiple memos, all with different contents. It's not possible to correctly convey memos to a user without using the concept of an output, but as a user, I probably don't work with outputs directly, my wallet does that for me.
-
Unlike Zcash, we support multiple asset types, and thus are likely to have multiple outputs in a single transaction. For instance, suppose I have shielded ATOM on Penumbra, I send some to someone else, and I'm using UM to pay fees. Then my transaction will have at least three outputs: one for the recipient, two for me (ATOM change, UM change). Of those three, two are self-addressed and will have meaningless memo contents. So we're paying >1KB per transaction for useless data.
Those points suggest to me that we would benefit from making the memo be a transaction-level field.
- Zcash is only capable of transfers from one address to another, while Penumbra supports more complex functionality. This means that "prevent someone from learning whether a transaction is a transfer to someone else" is a less coherent goal: if I see a transaction submitting a swap, I can be reasonably sure that that transaction only involves the creator, and isn't a transfer to someone else.
This suggests that in some cases, not including a memo may not reveal additional information about the transaction. So we could even consider making the memo field be optional. Or, perhaps we decide that having 528 bytes per transaction is relatively low overhead compared to the size of actions in a useful transaction, so we may as well require it.
I think it would make sense for us to have per-transaction Memo
s. What would this look like, exactly?
- We'd lift the
Memo
to the transaction level. This memo would be encrypted with some key. - The memo should be visible by all transaction recipients (each
Output
) as well as the transaction sender.
So, I think we just need to replace the current memo with another layer of key wrapping (generate a random key to symmetrically encrypt the memo, and for each output, encrypt it with the key used to encrypt that output's note plaintext.
for each output, encrypt it with the key used to encrypt that output's note plaintext
I think we want to do this, and also encrypt it with the OVK of the sender, so that in any given transaction with N outputs, there are N+1 wrapped keys. This means that even if you don't get a change note in a given transaction, you can still decrypt the memo you sent.
You'd get that anyways, I think, because the key used for note encryption is already encrypted to the OVK (that's the ovk_wrapped_key
).