Moving a Key from One TSM to Another TSM
Suppose we have two TSMs, which we will call TSM A and TSM B, that we have generated a key with keyID
in TSM A as explained here, and that we want to obtain a copy of this key in TSM B.
We will assume that TSM A consists of two MPC nodes, with player indices 1, 2, respectively operated by the two SDKs clientA1
and clientA2
. We will also assume that TSM B consists of two MPC nodes, with player indices 1, 2 and operated by SDKs clientB1
and clientB2
.
You first need to obtain the wrapping keys from the target TSM (TSM B):
ctx := context.Background()
wrapB1 := clientB1.WrappingKey().WrappingKey(ctx)
wrapB2 := clientB2.WrappingKey().WrappingKey(ctx)
Then you request a key export MPC session on the source TSM (TSM A). Since this is an MPC session, you first need to pick a session ID and set up the MPC session configuration:
players := []int{1,2}
sessionID := tsm.GenerateSessionID()
sessionConfig := tsm.NewSessionConfig(sessionID, players, nil)
derivationPath := []uint32{} // Export the key itself, not a key derived from the key.
Then run the key export MPC session, by calling the two SDKs on the source TSM (TSM A) concurrently:
// These calls will block until the MPC session is done, so make sure to
// run the two calls in separate processes or goroutines.
share1, err := clientA1.ECDSA().ExportKey(ctx, sessionConfig, keyID, derivationPath, wrapB1)
share2, err := clientA2.ECDSA().ExportKey(ctx, sessionConfig, keyID, derivationPath, wrapB2)
Each output share consists of a wrapped key share, the wrapped chain code (which is used for key derivation), and the public key. Finally, run another MPC session on the target TSM to import the wrapped key shares:
players := []int{1,2}
sessionID := tsm.GenerateSessionID()
sessionConfig := tsm.NewSessionConfig(sessionID, players, nil)
// Again, run the next two calls in separate processes or goroutines
keyID, err := clientB1.ECDSA().ImportKey(ctx, sessionConfig, threshold, share1.WrappedKeyShare, share1.WrappedChainCode, keyShare1.PKIXPublicKey, desiredKeyID)
keyID, err := clientB2.ECDSA().ImportKey(ctx, sessionConfig, threshold, share1.WrappedKeyShare, share2.WrappedChainCode, keyShare2.PKIXPublicKey, desiredKeyID)
The threshold
is the security threshold for the imported key. This must equal the threshold that you used when you generated the key.
The desiredKeyID
is optional. If provided, this will be the ID of the imported key. This can be used to make sure that the key ends up with the same ID in both TSMs.
Note
The current import and export methods require that the MPC destination nodes have the same player indices as the source MPC nodes, and the security threshold of the key sharing among the destination nodes will be the same as the security threshold of the sharing among the source nodes.
Code Example
Running code examples of this can be found in our demo repository: Go, Java, node.js.
Updated 15 days ago