0xMiden / 0xMiden/rust-sdk

Store decryption keys in the client

Open
#1,613 4 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
78
Forks
129
Avg merge
4d 14h
Merged PRs (30d)
52

Description

As we move to [encrypting the notes sent over the transport layer](https://github.com/0xMiden/miden-note-transport/issues/48), we need to support decryption in `miden-client`. Specifically, we need to:
1. Generate a new key pair
2. Store the decryption key in some key store
3. Share the encryption key as part of `Address` that we give out
4. 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:
1. How many key pairs and how to associated them to the accounts?
1. one key pair per client instance,
2. one key pair per account,
3. or let users arbitrarily choose the association?
2. 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 `NoteTag` derived for each account is unique
- but when sharing their `Address`, the `RoutingParameters` will 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 `Address` variant.
- 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 that `Address` only.

This will be partially informed by the decisions of how we generate and store decryption keys.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.