Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lift Memo to transaction level #1222

Closed
redshiftzero opened this issue Jul 27, 2022 · 5 comments · Fixed by #1371
Closed

lift Memo to transaction level #1222

redshiftzero opened this issue Jul 27, 2022 · 5 comments · Fixed by #1371
Assignees

Comments

@redshiftzero
Copy link
Member

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?
@redshiftzero
Copy link
Member Author

Looks like there's a similar discussion over in zcash land: zcash/zips#627

@hdevalence
Copy link
Member

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.

@hdevalence
Copy link
Member

I think it would make sense for us to have per-transaction Memos. 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.

@plaidfinch
Copy link
Collaborator

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.

@hdevalence
Copy link
Member

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging a pull request may close this issue.

3 participants