boltlabs-inc / tss-ecdsa

An implementation of a threshold ECDSA signature scheme
Other
11 stars 5 forks source link

Implement export functionality of key shares #537

Open jakinyele opened 1 month ago

jakinyele commented 1 month ago

The goal of this ticket is to provide backup and restore functionality in tss-ecdsa for private key shares. Specifically, we need the ability for users of the library to export their private key shares securely with a given public encryption key. Participating nodes will use the key to encrypt the key shares and return all of the encrypted shares to the caller of the library.

We will need convenience functions that allow a user of the library to locally decrypt the key shares with a given private decryption key and then recombine into a whole private key. Note that this functionality should not be part of the core library but potentially part of a higher-level wrapper SDK or a separate crate that wraps the tss-ecdsa.

Things to discuss prior to implementation:

becgabri commented 1 month ago

Some light notes on implementation decisions. The tss-ecdsa library should probably only provide an interface to export keys encrypted under a public key for a CCA2 secure encryption scheme. So something of the form ExportKey(public_key). These shares can then be decrypted and recombined by the caller.

From this perspective, we should probably support one well known pke that is CCA2 secure. I would favor something like ECIES, but there may not be many good libraries out there that provide an implementation, since ECIES requires you to choose an elliptic curve, a KDF, a MAC, and a symmetric encryption scheme. If we can't find a good library we would have to build it ourselves. Although it is not ideal, if it is too difficult to find a good implementation or we don't trust ourselves to come up with one, we could just use RSA-OAEP since the data we want to encrypt is so small. At the very least we must provide very clear documentation on what the schemes are and how to generate a key. We could potentially include a function like GenerateExportKey() but I'm not sure how much sense it makes to include this in the library itself. You could just use open-ssl to derive either an RSA-OAEP key or to derive a ECDSA key which can be repurposed to work with ECIES (although this is kind of hacky and I'm wary of doing this because we would need to be really careful with the format of the verification/public key).

When building this we should also keep in mind that this type of functionality could be a pretty dangerous foot gun for users and we should try to make this very clear in documentation as well.

becgabri commented 1 month ago

We’re amending this ticket to try and give users of this library more flexibility in how they choose to implement this functionality. In particular, we would like this function to instead take as input a type that implements a trait called Pke which has method signatures encrypt and decrypt.

pub fn export_keyshare(key_share: &KeySharePrivate, receiver_pk: &PublicKey, sender_sk: &SecretKey) -> Result<Self>

to something like

pub fn export_keyshare<T: Pke>(key_share: KeySharePrivate, pke: &T) -> Result<Self>

where Pke offers both encrypt and decrypt functionalities. The current work using sodiumoxide can then be put into an object that implements the Pke trait. It might also be easier to have the trait return a binary string type object i.e Vec<u8> then to have an EncryptedKeyShare type. Feel free to do what makes the most sense to you, this is just a general guideline of what we are looking for.

** earlier this said we wanted to change the naming from import/export to something else but we decided it makes the most sense to keep that language the same