TSM Local Deployment
This page describes how to set up a minimal (3, 1) TSM using docker-compose, which can compute ECDSA signatures and is suitable for local development.
This article describes how to deploy the TSM itself. If you already have a TSM and want to connect to it using a SDK, you can get more information here.
Logging in to Blockdaemon's docker registry
Start by login into Blockdaemon's private docker registry using the credentials you were provided:
docker login nexus.sepior.net:19001
Create TSM configuration
The three MPC nodes will communicate internally on port 9000 using docker-composes built-in DNS server. They will also expose one SDK port per TSM, these will be mapped to 8000, 8001 and 8002 on localhost for testing and development.
Each of the three MPC nodes needs a private/public keypair. To generate this run:
$ openssl ecparam -name P-256 -genkey -param_enc named_curve -outform DER -out private0.key
$ openssl ec -inform DER -in private0.key -pubout -outform DER -out public0.key
$ openssl ecparam -name P-256 -genkey -param_enc named_curve -outform DER -out private1.key
$ openssl ec -inform DER -in private1.key -pubout -outform DER -out public1.key
$ openssl ecparam -name P-256 -genkey -param_enc named_curve -outform DER -out private2.key
$ openssl ec -inform DER -in private2.key -pubout -outform DER -out public2.key
The above requires a fairly new version of OpenSSL, so if you encounter any issues running the commands, please try and update your OpenSSL and try again.
Next, we need to create a configuration file for each of the three TSMs, let's start with config0.toml
.
Get node 0's private key in base64:
$ openssl base64 -A -in private0.key; echo
Then get all the nodes' base64 encoded public keys:
openssl base64 -A -in public0.key; echo
openssl base64 -A -in public1.key; echo
openssl base64 -A -in public2.key; echo
We are now ready to create config0.toml
by putting in the generated values in the following template. Under [Player]
replace <node ID
> in Index
with 0. Also, replace <private key>
in PrivateKey
with the output from above. Under [Player.N]
where N
is 0..2
replace <nodeN public key>
in PublicKey
with the output from above. Replace <SDK port>
in Port
under [SDKServer]
with 8000
and <MPC port>
under [MPCTCPServer]
with 9000
.
# General configuration for MPC operations.
[MPC]
# This is the security threshold for the TSM. It means that the TSM is secure as long as at most threshold number of
# players are corrupt. Must be greater than 0 and less than the total number of players. Some MPC protocols have
# restrictions on what the threshold can be.
Threshold = 1
# Configuration for the local player
[Player]
# All players in a TSM are identified by a player index. This is the index of the player running this TSM node.
# We refer to this player as the local player. Other players are called remote players.
Index = <node ID>
# This is a base64 encoding of the private key used to authenticate the local player towards the remote players. This
# must correspond to the public keys configured on the remote players for this player index. A private key can be
# generated using the following OpenSSL commands:
PrivateKey = "<private key>"
# The following is a list of remote players in the TSM.
#
# The logic is that lower numbered players open connections to higher numbered players, so URLs are not needed for players
# with a lower number than the local player.
[Players.0]
# The protocol and address of player with index 0. Supported protocols are tcp, ws and wss. If no protocol is
# specified then tcp is assumed.
Address = "tcp://node0:9000"
# This is a base64 encoding of the players public key.
PublicKey = "<node0 public key>"
[Players.1]
Address = "tcp://node1:9001"
PublicKey = "<node1 public key>"
[Players.2]
Address = "tcp://node2:9002"
PublicKey = "<node2 public key>"
# Database connection configuration.
[Database]
# The driver used for the database. The following database drivers are supported: sqlite3, mysql and postgres.
DriverName = "sqlite3"
DataSourceName = "/tmp/tsmdb"
# This specifies a master encryption key used to protect database records. Note that this key is not directly
# used to encrypt data. Use any long random string here and make sure to keep a backup of it somewhere safe.
EncryptorMasterPassword = "ENCRYPTION_KEY"
# MPC server accepting multiplexed TCP connections from other players.
# At least one MPC server must be specified if the player index is greater than 0.
[MPCTCPServer]
# Port number that this server listens on.
Port = <MPC port>
# Server accepting connections from the SDK. This must be specified unless the TSM node is running as a local node.
[SDKServer]
# Port number that this server listens on.
Port = <SDK port>
# Configures system logging for the TSM node.
#[Logging]
# Log level. If not specified it default to "info".
#Level = ""
# Computes ECDSA signatures. This protocol requires n >= 2t+1. Cannot be enabled together with DKLS18 or DKLS19.
[SEPH18S]
The above should be repeated for config1.toml
and config2.toml
using the appropriate values. Do not forget to use the correct SDK ports and MPC ports for each.
Note that in production SDK port needs to be different, this is done here because we need all of them bound to localhost.
Note, EncryptorMasterPassword
should be different per node in a production deployment.
Starting the TSM
To start the TSM with docker-compose
create a file docker-compose.yml
with the following contents:
version: "3.8"
services:
node0:
image: nexus.sepior.net:19001/tsm-node:latest
ports:
- "8000:8000"
networks:
- tsm
environment:
- CONFIG_FILE=/config/config0.toml
volumes:
- ./config0.toml:/config/config0.toml
node1:
image: nexus.sepior.net:19001/tsm-node:latest
ports:
- "8001:8001"
networks:
- tsm
environment:
- CONFIG_FILE=/config/config1.toml
volumes:
- ./config1.toml:/config/config1.toml
node2:
image: nexus.sepior.net:19001/tsm-node:latest
ports:
- "8002:8002"
networks:
- tsm
environment:
- CONFIG_FILE=/config/config2.toml
volumes:
- ./config2.toml:/config/config2.toml
networks:
tsm:
Execute docker-compose up
from the same directory where you save docker-compose.yml
. A TSM should now be reachable for the SDK on ports 8000, 8001 and 8002 on localhost.
Advanced configuration
See Example TSM configuration file for further configuration hints.
Updated 8 months ago