# 🔑  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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://services.validexis.com/validator-security-our-approach-and-protection-measures/horcrux.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
