sRFC 00007 - Encryption Standard for Solana Keypairs

As the Solana ecosystem evolves, the need for an encryption standard for Solana key-pairs becomes increasingly important for securing sensitive data such as account state or files on distributed file systems like IPFS and Arveawe. While Ed25519 key-pairs are effective for signing messages, they are not usable for asymmetric encryption, which is crucial for user privacy and data protection.

To address this issue, I propose creating a standard for converting Ed25519 key-pairs to Curve25519 key-pairs that are designed for the Diffie Hellman Key exchange protocol, which would enable asymmetric encryption without having to generate seperate keys to perform this kind of action. This conversion allows users and software wallets to leverage libraries like TweetNaCl for robust and easy-to-use encryption implementations.

Implementing an encryption standard for Solana key-pairs would give Solana one more use-case which could drive a lot of traction to the chain.

I made a reference implementation as a feature for this kind of conversion in the Wallet Adapter example repository. Check it out here: wallet-standard/solanaWallet.ts at encryption · valentinmadrid/wallet-standard · GitHub

While there is a consensus within the Solana community that encryption is essential, there may be different approaches to implementing it; thus, I welcome everyone to provide their feedback and suggestions on this proposal to ensure the most effective solution is adopted.


Here is a demo implementing the conversion from Ed25519 to Curve25519 keypairs showing off the performance and safety of using Tweetnacl using these: :grin:
The following paper suggests that such a “conversion”/usage for signing and encryption using the same key should be safe: On the Joint Security of Encryption and Signature in EMV
This answer on the cryptography Stackexchange suggests the same thing: What happen if the curve used in key agreement protocol also used in signature inside of protocol? - Cryptography Stack Exchange

Again, this proposal has been made to come to an agreement on how Solana Keypairs should be derived to be compatible for Diffie Hellman Key exchange or other kinds of encryption mecanisms. Once an agreement on this topic is reached, wallets could start to implement encryption features as part of the Wallet Standard.


As an alternative to deriving a Curve25519 keypair from a regular Solana Keypair to perform encryption, Jordan Sexton suggested that a keypair could be derived from a signed message by any wallet to derive an encryption key(including hardware wallets).
This could have upsides to my proposal, you can read about his suggestion here:
A concern with this approach may be that the cryptography could be broken once two dApps request a signature with the same seed. There would be a need for some kind of one time nonce that has to be different on each encryption, which would be hard to achieve.


deriving a keypair from a signed message by a wallet as an encryption key looks nice.
can having 4-8 digit PIN manually entered by the user be used a seed to be signed ?
can this help in avoiding seed collision ?

1 Like

This is how we’ve agreed on this proposal for now:

  1. The user provides an input message (plaintext) intended for encryption, along with the recipient’s public key, and invokes the encryption function available in the browser’s window.
  2. The plaintext message is passed on to the encryption module within the user’s digital wallet.
  3. The wallet derives a Curve keypair from the signature generated by the user’s stored keypair. The size of the derived Curve keypair is determined by the byte length of the signature.
  4. The wallet then performs a box encryption operation (asymmetric) utilizing the tweetnacl cryptographic library. The encryption process incorporates: a. The recipient’s public key b. The plaintext message c. A randomly generated nonce (number used once) by the wallet d. The Curve keypair, which has been derived from the signature
  5. Upon successful encryption, the wallet outputs the resulting ciphertext and the generated nonce to the user.

This constraint implies that dApps must implement a mechanism to handle the storage, retrieval, and sharing of public keys associated with encryption. The dApps could maintain an on chain program or database, which stores public keys provided by wallet holders explicitly for encryption purposes.

Please give me your thoughts on this.


the Idea behind having a PIN than a fixed string was that ,when the user enters that specific PIN, the wallet signs it to derive a new Curve keypair. so the derivation of Encryption keypair is dependent on the PIN.
Advantage : PIN acts as another layer of security to the cipher text
DisAdvantage : Decryption cannot happen if the PIN is lost/ forgotten

FYI : just wanted to explore some new directions… might not be the best way…

A PIN would mean the encryption Keypair would not be recoverable using a private key if the PIN is lost, therefore the mecanism to prevent the encryption from being broken is that the wallet generates a random nonce additionally to the deterministic message for the encryption that is given back to the client afterwards. The random generated nonce by the wallet can be publicly shared.

Just wanted to circle back here to share an update on this sRFC workflow!

@jordaaash and I have been working on an implementation for exactly this, with an on-chain program.

I’ve documented how this program works in the repository’s README, but the TL/DR is:

  • This program does exactly what @valentin suggested: stores public keys associated with encryption
  • It makes use of a “Keystore” PDA mapped to a particular wallet address
  • It’s specifically tailored to implement serialization/deserialization in the off-chain client, so that the program can remain frozen while new encryption algorithms may be added in the future
  • It’s inception should go hand-in-hand with a robust review process - akin to sRFCs or simply Pull Requests - to add support for new encryption algorithms

At the time of writing this reply, the encryption algorithms depicted in the client are for demonstration purposes only, and any associated configurations may look different than this spec in production.

The implementation is also in active development and subject to change.

Would love anyone’s feedback on the code, though!!