Skip to main content

Key Generation Ceremony

The ceremony is a one-time event. It generates the key shares that underpin all future signing. Run it in a controlled environment with at least two people present.


Section 1 — Setup

import * as crypto from 'crypto';
import * as fs from 'fs';
import { WorkspaceClient, ComponentModule } from 'caller-sdk';

const workspace = new WorkspaceClient({ apiKey: process.env.WR_API_KEY! });
Key concept — threshold and servers

White Rabbit MPC uses threshold signatures. With threshold: 2 and 3 servers, any 2 of the 3 nodes can jointly sign — but no single node holds enough material to act alone. This is the same model used by institutional custodians (Fireblocks, Copper, etc.).

PropertyWith threshold: 2, servers: 3
AvailabilityOne node can go offline without interrupting signing
SecurityAttacker must compromise 2 independent nodes simultaneously
RecoveryAny 2 custodian shards can restore a missing node

Section 2 — Generating the Key Shares

async function keyGenerationCeremony(): Promise<{
keyId: string;
rootPublicKey: string;
}> {
// Generate a 2-of-3 threshold key across all three official MPC nodes.
// The raw private key is NEVER assembled at any point during this operation.
const { keyId, rootPublicKey } = await workspace
.call(ComponentModule.GENERATE_KEY_SHARE, {
curve: 'SECP256k1', // EVM and Bitcoin — change to 'ED25519' for Solana
threshold: 2,
})
.promise();

// ⚠️ Persist keyId immediately — this is your only handle to the shares.
// Loss of keyId = permanent loss of access, no recovery path.
await db.saveKeyId({ keyId, rootPublicKey, createdAt: new Date() });

// Also write a local backup in case the DB write fails
fs.writeFileSync('./keyId-backup.json', JSON.stringify({
keyId,
rootPublicKey,
createdAt: new Date().toISOString(),
}, null, 2), { mode: 0o600 });

console.log('Key generated. keyId:', keyId);
console.log('Root public key:', rootPublicKey);

return { keyId, rootPublicKey };
}
Key concept — keyId is irreplaceable

The keyId is a UUID that maps to your key shares inside the MPC nodes. It is not a seed phrase. If you lose it, the shares are orphaned and inaccessible — there is no recovery path.

Store it in:

  1. Your primary database
  2. A secondary read replica
  3. A printed physical copy in a secure facility (e.g. a fire-rated safe)

Loss of keyId is treated the same as loss of all key material.

Key concept — rootPublicKey

The rootPublicKey is the combined public key derived from all shares. It is safe to publish. Record it separately so you can verify that a restored or migrated key still maps to the same on-chain address — a mismatch means something went wrong during an import cycle.


What happens next

After the ceremony, the key shares exist on all 3 MPC nodes. Do not leave them there. The next step is to export each shard to a custodian and delete it from the node, so nodes are empty at rest.

Continue to Custodian Setup & Shamir Secret Sharing →