> For the complete documentation index, see [llms.txt](https://services.validexis.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://services.validexis.com/validator-security-our-approach-and-protection-measures/horcrux.md).

# 🔑  Horcrux

Horcrux is a distributed signing tool that splits the validator's private key into multiple parts, ensuring its security. This approach prevents key compromise even if one part is accessed.

***

### Preparing the Infrastructure

Horcrux requires at least **two servers** (three or more are recommended) to split the key. Setup involves:

**Horcrux servers** for distributed signing.

**Validator node** to interact with the blockchain network.

Ensure the following:

1. **SSH access** and server setup.
2. Install Horcrux on each server.
3. Configure firewalls to allow communication between servers on the Horcrux ports.
4. **Time synchronization**: Make sure all servers use NTP for synchronized time.

```bash
sudo apt install ntp  
sudo systemctl enable ntp  
sudo systemctl start ntp
```

***

### Server Requirements for Horcrux-Based Validator Setup

#### Signer Nodes (Horcrux Co-signers)

**Type:** VPS (Virtual Private Server)\
**Recommended Specifications:**

* **CPU:** 4 vCPU
* **RAM:** 4 GB
* **Storage:** 80 GB NVMe SSD
* **Network:** 1 Gbps bandwidth

**Required Open Ports:**

* **2222** — for communication between Horcrux co-signers
* **SSH (22)** — for remote administration
* **Prometheus port** (optional, if using monitoring)

#### Sentry Nodes (Validator Nodes or Observers)

**Type:** Bare-metal or VPS\
**Recommended Specifications:**

* **CPU:** 4 vCPU
* **RAM:** 16 GB
* **Storage:** 250 GB SSD
* **Network:** Stable and fast connection

**Required Open Ports:**

* **1234** — private port for connection from Horcrux signers
* **26656** — P2P port for communication with the blockchain network

### Update system and install build tools

```bash
sudo apt -q update
sudo apt -qy install curl git jq lz4 build-essential
sudo apt -qy upgrade
```

### Install GO

```bash
sudo rm -rf /usr/local/go
curl -Ls https://go.dev/dl/go1.23.6.linux-amd64.tar.gz | sudo tar -xzf - -C /usr/local
eval $(echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/golang.sh)
eval $(echo 'export PATH=$PATH:$HOME/go/bin' | tee -a $HOME/.profile)
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
go version
```

### Installing Horcrux

Run the following commands on **each co-signer node**:

```bash
git clone https://github.com/strangelove-ventures/horcrux.git
cd horcrux
make install
```

After installation, verify it with:

```bash
horcrux version
```

### Initialize Horcrux Configuration

Run the following command on **one of the co-signer nodes** to generate the shared configuration:

```bash
horcrux config init \
  --node "tcp://<VALIDATOR_IP>:1234" \
  --cosigner "tcp://<COSIGNER_1_IP>:2222" \
  --cosigner "tcp://<COSIGNER_2_IP>:2222" \
  --cosigner "tcp://<COSIGNER_3_IP>:2222" \
  --threshold 2 \
  --grpc-timeout 1000ms \
  --raft-timeout 1000ms
```

> 🔧 **Note:**
>
> * Replace `<VALIDATOR_IP_X>` with the actual IP addresses of your validator (or sentry) nodes that expose the `priv_validator_laddr` port (`1234`).
> * Replace `<COSIGNER_X_IP>` with the IPs of each co-signer node using port `2222`.
> * The order of the `--cosigner` flags determines which shard (`cosigner_1`, `cosigner_2`, `cosigner_3`) goes to which server. Be consistent when distributing keys and configuration files.

#### Generate ECIES Keys (for Secure Communication Between Co-Signers)

Run this once to generate the ECIES encryption keys:

```bash
horcrux create-ecies-shards --shards 3
```

This will create the following directory structure:

```bash
./cosigner_1/
  ecies_keys.json
./cosigner_2/
  ecies_keys.json
./cosigner_3/
  ecies_keys.json
```

#### Fragment the Validator Private Key

> ⚠️ Copy the `priv_validator_key.json` file from your **validator node** into your working directory **before** running this command.

Then run:

```bash
horcrux create-ed25519-shards --chain-id <CHAIN_ID> --key-file ./priv_validator_key.json --threshold 2 --shards 3
```

This will update the structure:

```bash
./cosigner_1/
  <CHAIN_ID>_shard.json
  ecies_keys.json

./cosigner_2/
  <CHAIN_ID>_shard.json
  ecies_keys.json

./cosigner_3/
  <CHAIN_ID>_shard.json
  ecies_keys.json
```

✅ At this point, you should move `priv_validator_key.json` to a **secure storage location** — it is no longer needed in the signer environment.

### Distribute Config Files to Co-Signer Nodes

Each co-signer node must have the following files placed in their respective `~/.horcrux/` directory:

```
~/.horcrux/
├── config.yaml
├── ecies_keys.json
├── <CHAIN_ID>_shard.json
└── state/
    └── <CHAIN_ID>_priv_validator_state.json
```

> ❗ **Important:**\
> Ensure that each cosigner receives **only their own** files according to the order in which you ran `horcrux config init` and generated shards (i.e., cosigner\_1, cosigner\_2, cosigner\_3).

### Setting Up the Horcrux Service

**Create a service file**: On each server, create a file at `/etc/systemd/system/horcrux.service`:

```ini
sudo tee /etc/systemd/system/horcrux.service > /dev/null << EOF  
[Unit]  
Description=MPC Signer node  
After=network-online.target  
[Service]  
User=$USER  
WorkingDirectory=/home/$USER  
ExecStart=$(which horcrux) start  
Restart=on-failure  
RestartSec=3  
LimitNOFILE=4096  
[Install]  
WantedBy=multi-user.target  
EOF
```

**Start and check the service**:

```bash
sudo systemctl daemon-reload  
sudo systemctl enable horcrux.service
sudo systemctl start horcrux.service  
sudo systemctl status horcrux.service  
```

### Share Consensus State Between Signers

Each signer node must start from the **same consensus state** to avoid double-signing.

#### 🛑 On the validator node:

```bash
sudo systemctl stop <node_service>
```

1. Open the validator's consensus state file:

   ```bash
   cat .<NODE_HOME>/data/priv_validator_state.json
   ```

   Example output:

   ```json
   {
     "height": "6513530",
     "round": 0,
     "step": 3,
     "signature": "IEOS7EJ8C6Z...",
     "signbytes": "6B080211BA83..."
   }
   ```
2. Create a **stripped-down version** of this file to be placed in each co-signer’s state directory:

   ```json
   {
     "height": "6513530",
     "round": "0",
     "step": 3
   }
   ```
3. Copy this file to all co-signer nodes as:

   ```
   ~/.horcrux/state/<CHAIN_ID>_priv_validator_state.json
   ```

### Configuring the Validator Node

* Update the validator's configuration file: In the `config.toml` file of your validator node, specify the remote Horcrux address for signing:

```toml
priv_validator_laddr = "tcp://0.0.0.0:1234"
```

* Restart the validator:

```bash
sudo systemctl restart <node_service>
```

**Check Horcrux logs:**

```
sudo journalctl -u horcrux -f
```

### Monitoring and Testing

* **Check connectivity**: Ensure the validator node successfully connects to the Horcrux servers.
* **Test signing**: Verify transactions are signed correctly by creating a test transaction on the network.
* **Setup monitoring**: Use tools like Prometheus and Grafana to monitor the validator and Horcrux servers.

***

### &#x20;Security Recommendations

* **Isolate Horcrux servers**: Restrict access to only the validator node.
* **Keep software updated**: Regularly update Horcrux and the operating systems.
* **Backup configuration**: Store copies of the configuration and key shares in a secure location.
