EIP-5630: Encryption and Decryption

This is awesome work. It lends itself nicely to extension as well. One such way would be to use a contract as a public key registry. This effectively enables decentralized private file sharing. I was doing previous work on this here, with the former EIP-1024.

I think this EIP has the potential to open up a bunch of use cases based on work like this. I think the “person → person” or “person → people” categories are easily opened up as well. Again using an extension to this methodology through a contract. The same code shared above has a methodology to share a encrypted file to a group of people. I think the use case for people to communicate over encrypted channels itself is very compelling and important. Not to mention in the current form it fits nicely into permissionless building.

1 Like

For the key discovery or public key registry, I think it is time to summarize:

  1. Smart Contracts could expose a function to return a public key;
  2. EOA: encrypt to the “direct” public key, that is, the one corresponding to the address. Usually this could be recovered from past signatures. We need a utility for this purpose.
  3. EOA: encrypt to the “derived” public key as currently specified. We may need a registry, be it smart contract or ENS or something else. Fee may incur.

There are also security implications to the choice between “direct” or “derived” public key, mostly about key management.

I’d like to link this to my other proposal about private key encapsulation: that is, if we rely on this EIP for file encryption or end2end encrypted messaging, we don’t want to enter our seed to a messaging app. We could safely transport the needed private key (“direct” or derived) to the app without endangering the entire seed.

1 Like

hi @Weiji.

let’s back up—i don’t see why there would ever be a need to input your seed into a messaging app?

let’s take an example. in the case of e2e messaging, it’d work the following way. the “dapp”—which, i emphasize, is just some static javascript loaded into the browser—will perform the following steps to send a message:

  • it would acquire the recipient’s public key, either by doing an ECDSA recovery on an existing signature (“direct”) or retrieving it from a registry (“derived”).
  • it would solicit the desired plaintext message from the user, through some kind of input form.
  • it would run some local javascript code to encrypt this plaintext to the desired recipient’s key.
  • it would prompt the user to post this ciphertext on-chain, and to pay the gas for doing that.

to receive / decrypt a message, the dapp would do as follows:

  • it would retrieve the relevant ciphertext(s) from an on-chain source, e.g., the user’s “inbox” contract.
  • the (static) dapp code would issue an eth_decrypt request to the user’s wallet, with the ciphertext as argument. the user will be prompted to approve the decryption.
  • the plaintext will now be displayed by the dapp web interface.

there is never a need to expose the seed or any private material whatsoever to the dapp, or to any remote server.

hopefully this helps clarify things? thanks for your thoughts.

Consider if the user is keeping his or her seed or private keys in a hardware wallet, yet the dapp runs in a mobile device or browser extension for convenience. If we rely on the hardware wallet to decrypt, then literally user will have to approve the decryption for every incoming message. And if he or she leaves the hardware at home, there is no way to decrypt messages for the day.

so yes, this is true. but usually we accept and even expect user approval for each sensitive action. but if you wanted to bypass this, you could use the following flow instead.

to log in / create an account:

  • the browser client generates a fresh random secret key for the user, say nk. it locally computes the corresponding public key, say mk.
  • the browser posts mk in a registry known to the dapp, so that other users can discover the key mk.
  • the browser separately issues an eth_getEncryptionPublicKey request to the wallet, which the user is prompted for; it receives the resulting stable public encryption key, say ek.
  • it encrypts the secret nk to ek, and posts the resulting ciphertext to the blockchain somewhere belonging to the user, for recovery later.
  • to log back in later, the browser retrieves this ciphertext, and issues an eth_decrypt request on it to the user. after the user accepts the request, the browser obtains nk, which it can use to decrypt every message.

to send a message:

  • after inputting the desired recipient into the dapp, the dapp retrieves the dapp-specific public key mk corresponding to this receipient.
  • the dapp solicits the plaintext from the user, encrypts it to mk, and posts the ciphertext on-chain.

to receive a message:

  • once you’re logged in (see above) the browser has access to nk, using which it can automatically retrieve / decrypt every message.

in this case, you do provide the secret nk to the dapp. but this secret is completely unconnected to your seed phrase hierarchy, and is not used for any purpose other than the dapp. moreover, there is no need for TLS / Diffie–Hellman / key encapsulation / etc., since the dapp runs locally on the same machine as the wallet—nk is never transmitted to any external machine. thoughts?

Hi @firnprotocol Key management is a complicated issue and not a pure technical decision. Sometimes it involves uers. Let’s focus on this EIP here and redirect KEM related discussion to the other thread. Do you mind if quote your comments there?

absolutely, go ahead.

@firnprotocol What do you think about this? Do you see a need to include it in 5630? It’d simplify public key discovery issues in some applications/scenarios.

right, yes, i think it’s a great idea. i just think we need to first decide (i.e., as a community) whether we want to include the HKDF or not (i.e., whether we do 2 or 3 in the message you’re quoting from).

  • benefit of using HKDF: slightly stronger security (i.e., security argument doesn’t rely on the GGM).
  • benefit of not using HKDF: allow key discovery by performing ecrecover on existing signatures.

which benefit is more “worth it” first needs to be decided by us, on technical grounds.

i’m not quite sure what you mean. certainly the decision of whether to use the HKDF or not needs to be made in this EIP.

on the other hand—regardless whether or not we include the HKDF—my sense is that the mechanism for public key discovery is out-of-scope for this EIP. if we don’t use the HKDF, then there’s not much of a problem to solve, since it’s essentially trivial (at least for addresses which have signed before). If we do use the HKDF, then it becomes much less trivial, and we’d need something analogous to ENS. either way though, i think that would be the territory of a separate EIP. thoughts?

I do think it is important for an EIP to be considered for its infrastructure dependencies. Public key discovery is non-trivial and subtle to manage right. And when such is lack we need to jump start this EIP.

Can we support both? Then users and community could choose either or both as they see fit. I do see applications without HKDF, when people can send each other encrypted messages as long as the peer had signed any txn/msgs before.

hmm. perhaps we could support both, and use separate version tags for each. e.g., secp256k1-sha512kdf-aes256cbc-hmacsha256 and secp256k1-sha512kdf-aes256cbc-hmacsha256-nokdf. (these are getting fairly long…). i’d personally prefer that we pick one, just for simplicity, but maybe we can let community members weigh on on this.

while i agree with you that it’s important and subtle, I think I have to respectfully disagree that it should be included in this EIP. i would be happy to help & advise on a separate EIP treating the issue of public key distribution / advertising.

Maybe simply secp256k1-aes256cbc-hmacsha256

This has been going around a few times. I totally respect your decision here. Let’s close it here.

1 Like

Before I submit a new pull request, let’s do a little bit polling here.

Do you think we need to add a new version secp256k1-aes256cbc-hmacsha256?

  • Yes
  • No

0 voters

The purpose of this new version is that applications could choose to encrypt message to the original public key or one derived with sha512kdf. Please checkout earlier discussion for context. Thanks.

in the interest of clarifying the poll…

do you intend that a “yes” vote entails that we do both? or that we only do the version without the KDF? if possible, please clarify that, and then i will vote.

btw, to clarify, the sha512kdf in the original naming suggestion refers to the KDF done within ECIES (to conver the DDH secret into an AES + MAC secret key). it has nothing to do with the KDF relating skdk, which is separate. just so you know.

both, sorry for the confusion

Thanks for the clarification. I assumed the wrong way. Then maybe the suggested additional version could be: secp256k1-none-sha512kdf-aes256cbc-hmacsha256, with none following immediately after secp256k1 to indicate that no KDF is done to derive dk from sk. The original version could also be changed to sth like secp256k1-X963-sha512kdf-aes256cbc-hmacsha256. I’d also suggest that we trim the trailing cbc-hmacsha256 as there is no other option here. How do you think? @firnprotocol

sure, I am happy to do this. the name is too long. good idea.

my opinion is that for simplicity, we should choose one approach for this EIP. i am not sure yet which it should be, but I think I have a preference against doing both. so I will have to vote “no” in the poll I think.

actually, personally, if I had to choose, I’d prefer not doing the KDF (as you suggested). it’s a question of whether the community will also agree—the security is (very) slightly weaker, since the best known proofs require the GGM.

@firnprotocol how about a new poll with 3 options, that is: both, with-kdf, without?

sure. (i’d prefer we exclude the option “both”, but let’s let the poll decide that :slight_smile:) thanks for putting this together.

How do you think we should proceed? Please select one:

  • support only the original verision secp256k1(-X963)-sha512kdf-aes256(cbc-hmacsha256), a new key pair for encryption/decryption is derived from sk
  • support only the new verision secp256k1(-none)-sha512kdf-aes(256cbc-hmacsha256), just use sk and its corresponding public key
  • support both versions

0 voters