-
Notifications
You must be signed in to change notification settings - Fork 79
Description
As we move to encrypting the notes sent over the transport layer, we need to support decryption in miden-client. Specifically, we need to:
- Generate a new key pair
- Store the decryption key in some key store
- Share the encryption key as part of
Addressthat we give out - Trial decrypt the notes fetched from the transport layer
And each comes with its own set of questions.
Generate a new key pair
Main questions:
- How many key pairs and how to associated them to the accounts?
- one key pair per client instance,
- one key pair per account,
- or let users arbitrarily choose the association?
- Based on the answer to the above, is the key automatically generated? If so, when?
My opinionated answer:
I think 1.iii is too complex and we can safely discard this option.
1.i is easy to manage for the client, but it does reduce privacy slightly. Consider the following scenario:
- user generates two accounts, and wishes to receive payments from two separate parties A & B
- the
NoteTagderived for each account is unique - but when sharing their
Address, theRoutingParameterswill include the same encryption key when shared with both A & B - while neither A, B, nor the transport layer can correlate the note ciphertext, A & B can collude to figure out they are sending to the same user (since the encryption key is the same)
With 1.i, the key is automatically generated upon client instantiation (if not present already).
1.ii does not suffer the same problem as 1.i, and I think it doesn't introduce much more complexity for the client: a key is automatically generated when the user requests a new account.
We can easily track (in the DB) which key corresponds to which AccountId / Address.
Store the decryption key
Once we have the answer to the above, the mechanics become straightforward.
The design question is whether we repurpose the existing {Filesystem/Web}Keystore (e.g. with a new trait e.g. EncryptionStore), or develop a fresh place to store encryption keys separately from signing keys.
Share the encryption key
Sharing the encryption key should be done via Address struct, which encodes the key as part of the RoutingParameters. The question is more for the UX / frontend side: how does the user decide whether to share an Address with or without the RoutingParameters?
- programmatically this could be easy, and I can see how this would be done in the wallet connector that we use e.g. for the faucet: the faucet frontend requests a encryption-ready
Addressvariant. - manually we need a clean way to not confuse the user yet still expose the relevant options cc @dagarcia7
Trial decrypt
I think this one is the easiest. The only question is whether we try all notes with all the decryption keys (if there are many)? Or do we have a smart way of associating which note should be decrypted with which key?
- @v0-e suggests to do the mapping of fetched tag -> respective owned
Address, and try the private key of thatAddressonly.
This will be partially informed by the decisions of how we generate and store decryption keys.