Key Lifecycle
Once we have already generated our key shares, we can refresh and also export them.
We show how to do this below.
Key Refresh
Key Refresh (sometimes referred to as "Key Rotation") is a protocol that allows the devices to compute entirely new secret shares of the same public key.
Refreshing the key material frequently is considered a best practice for enhanced security, as it adds an element of time to the security setting.
Since even if one secret share was compromised, then after Key Refresh the compromised secret share will no longer be useful.
Below is an example of how to use Key Refresh:
- ECDSA Go
- Ed25519 Go
import "github.com/sodot-rs/sodot-go-sdk"
const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
ecdsa := sodot.NewEcdsa("")
exportRoomUuid, err := ecdsa.CreateRoom(N, API_KEY)
if err != nil {
panic(err)
}
// Only one of the parties will receive the full private key, this party will retrieve its exportID:
exportTo, err := ecdsa.ExportID(secretShare);
if err != nil {
panic(err)
}
// It will the propagate this KeygenID to the other parties
// Threshold (t) parties will now need to join the export room
privkey, err := ecdsa.ExportFullPrivateKey(exportRoomUuid, secretShare, exportTo);
if err != nil {
panic(err)
}
// privkey is "" except for the party with exportTo as its KeygenID
// For the exporting party it will be a normal base58 string xpriv - more details in the link below
// It is most likely that importing the key elsewhere will only be supported for specific derivation paths
// Hence, it is possible to get the derived private key as well as public key for any derivation path
derivationPath := []uint32{44, 60, 0, 0, 0}
derivedPrivateKey, err := ecdsa.DerivePrivateKeyFromXpriv(privkey, derivationPath);
if err != nil {
panic(err)
}
derivedPubKey, err := ecdsa.DerivePubkey(secretShare, derivationPath)
if err != nil {
panic(err)
}
// derivedPrivateKey is the private key for derivedPubkey and can now be imported into any non-MPC based ECDSA signing software
API reference
Full details can be found here.
import "github.com/sodot-rs/sodot-go-sdk"
const N = 3
const T = 2
const API_KEY = "MY_API_KEY"
ed25519 := sodot.NewEd25519("")
exportRoomUuid, err := ed25519.CreateRoom(N, API_KEY)
if err != nil {
panic(err)
}
// Only one of the parties will receive the full private key, this party will retrieve its exportID:
exportTo, err := ed25519.ExportID(secretShare);
if err != nil {
panic(err)
}
// It will the propagate this KeygenID to the other parties
// Threshold (t) parties will now need to join the export room
privkey, err := ed25519.ExportFullPrivateKey(exportRoomUuid, secretShare, exportTo);
if err != nil {
panic(err)
}
// privkey is "" except for the party with exportTo as its KeygenID
// For the exporting party it will be an extended private key in a custom format (spriv) - more details in the link below
// It is most likely that importing the key elsewhere will only be supported for specific derivation paths
// Hence, it is possible to get the derived private key as well as public key for any derivation path
derivationPath := []uint32{44, 60, 0, 0, 0}
derivedPrivateKey, err := ed25519.DerivePrivateKeyFromSpriv(privkey, derivationPath);
if err != nil {
panic(err)
}
derivedPubKey, err := ed25519.DerivePubkey(secretShare, derivationPath)
if err != nil {
panic(err)
}
// derivedPrivateKey is the private key for derivedPubkey and can now be imported into any non-MPC based Ed25519 signing software
API reference
Full details can be found here.