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! });
threshold and serversWhite 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.).
| Property | With threshold: 2, servers: 3 |
|---|---|
| Availability | One node can go offline without interrupting signing |
| Security | Attacker must compromise 2 independent nodes simultaneously |
| Recovery | Any 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 };
}
keyId is irreplaceableThe 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:
- Your primary database
- A secondary read replica
- 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.
rootPublicKeyThe 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 →