Keyring program
Program for managing encryption keys.
Goals:
This program is designed to manage encryption public keys for various Solana wallets.
The Keyring Program leverages an account (PDA) dubbed a "Keystore" that houses all publicly available encryption public keys that the particular wallet owns and has made available in their keystore.
A user's keystore is mapped to their wallet address with the following Program-Derived Address seed pattern:
"keystore" + < wallet address >
The data of a KeystoreEntry
is structured in a nested TLV structure, which allows us to dynamically manage various types of keys and configs. (see below section)
A particular encryption algorithm may require some additional configurations or parameters to perform encryption/decryption. These can be specified in the (Additional configurations)
section in the structure layout below.
The nested TLV structure is formatted as follows:
* T: The new entry discriminator (marks the start of a new keystore entry)
* L: The length of the entry
* V: The data of the entry
* (Encryption key)
* T: The algorithm discriminator (provided by sRFC workflow)
* L: The length of the key
* V: The key itself
* (Additional configurations)
* T: The configuration discriminator (marks additional
configurations are present)
* L: The total length of the configuration data
* V: The configuration data
* (Configuration: `K, V`)
* T: The configuration key (provided by sRFC workflow)
* L: The configuration value length
* V: The configuration value
As you can see, within each entry we have a key and a configuration. The discriminator for the key will dictate the key's encryption algorithm and subsequently its length in bytes, while the discriminator for configurations will be akin to a boolean
or Option
. In psuedo-code:
Has configs: [<config discriminator>] [<length>] [<data>]
Does not have configs: [<no config discriminator>] -- no data
A key and its associated configurations can only be written to or removed from a particular keystore account if the authority has signed the transaction.
An authority must provide the entire buffer of data in order to successfully add or delete a key. When deleting, the program will match against the entire buffer that defines the key and associated configurations.
Typically a Solana program has well-defined state within its source code and one can use that source code to infer the exact byte-wise representation of the program's managed account data. However, this program actually cedes that state management over to it's tightly-coupled client.
More specifically, in order to ensure we can seamlessly add support for more encryption algorithms and their corresponding required configurations, the program-client relationship is designed as follows:
Along with this program we must establish a workflow for adding new encryption algorithms to the supported collection within the program's client(s).
A simple solution is to merely use GitHub Pull Requests directly into the client code itself, as the code has been written succinctly enough for these PRs to be straightforward to author.
When seeking to introduce support for a new encryption algorithm in the Keyring Program, one should submit a Pull Request with:
⚠️ Note: I would like to make this something like a publicly-hosted JSON that we can change without having to push any code changes, on- or off-chain.