Loading...
private.me Docs
Get xKey
PRIVATE.ME · Technical White Paper

Keysplit: Cryptographic Key Split Custody

Cryptographic keys are the ultimate single point of failure. Keysplit splits any key into shares distributed across independent custodians via XorIDA threshold sharing over GF(2). No single custodian holds a usable key. Information-theoretic security. 2-of-3, 2-of-5, K-of-N. HMAC-verified shares. Supports signing, encryption, root CA, and TLS keys. Zero npm dependencies.

v0.1.0 34 tests passing 5 modules 0 npm deps Information-theoretic HMAC-verified
Section 01

Executive Summary

Keys are the crown jewels of cryptographic infrastructure. A compromised root CA key, TLS private key, or signing key can undermine an entire security posture overnight. Keysplit eliminates single points of failure by distributing keys across independent custodians using threshold secret sharing.

The approach is mathematically elegant: split a key into N shares such that any K shares (K ≤ N) can reconstruct it, but K-1 shares reveal zero information — no matter how much computing power an attacker has. This is information-theoretic security, not computational security. It doesn't depend on the hardness of factoring, discrete log, or any other mathematical assumption. It's a law of mathematics.

Keysplit uses XorIDA (threshold sharing over GF(2)) — the same core cryptographic engine that powers the entire PRIVATE.ME platform. Split/reconstruct operations complete in microseconds. Every share carries an HMAC-SHA256 signature verified before reconstruction (fail closed). Supports 4 key types: signing keys, encryption keys, root CA keys, and TLS keys, each with extensible metadata for audit trails.

Two functions handle all use cases: splitKey() distributes a key across custodians; reconstructKey() recovers it from a threshold quorum. Zero npm dependencies. Runs on Node.js 20+, browsers, Deno, Bun, Cloudflare Workers.

Section 02

The Problem: Keys as Single Points of Failure

In traditional PKI, a single private key is the crown jewel. Lose it, and you've lost the identity behind it. Compromise it, and an attacker can forge signatures, impersonate you, or decrypt years of past traffic (if it was stored in ciphertext).

Current Approaches and Their Gaps

Approach Strengths Weaknesses
Single key on disk Simple One breach = total loss. No fault tolerance.
Hardware Security Module (HSM) Physical tamper resistance. Audit logs. Single point of failure. Vendor lock-in. High cost ($2K+/yr).
Multiple copies Redundancy against loss Each copy is a full key. Compromise any one = breach all.
Shamir's Secret Sharing Threshold-based security Computationally expensive (500–2000x slower than XorIDA). Limited to ~256 shares practical max. Not used in production.
Key escrow + recovery Recovery capability Trusted escrow agent is a single point of failure. Creates backdoor risk.

What Keysplit Solves

Keysplit eliminates the single point of failure by design. A key is split into N shares. Any K shares can reconstruct it. Any K-1 shares (or fewer) reveal absolutely nothing.

Information-Theoretic Security

Keysplit's security does not depend on the computational difficulty of any problem. An attacker with infinite computing power, a quantum computer, or a magic 8-ball cannot extract information from fewer than K shares. The security is a mathematical guarantee, not a bet on hardness assumptions.

Fault tolerance: If one custodian loses their share (hardware failure, forgot password, moved to a different organization), the key is still recoverable from the remaining shares as long as K custodians are available.

No trusted third party. A traditional key escrow requires a trusted agent who can decrypt recovered keys. Keysplit requires only a threshold quorum of custodians, none of whom can act alone. This is strictly stronger security.

Section 03

How Keysplit Works

Keysplit splits a cryptographic key into shares across custodians. It's a three-step pipeline: pad the key, compute an HMAC for integrity, split via XorIDA, and distribute shares to custodians.

Quick Start

Split and reconstruct example
import { splitKey, reconstructKey } from '@private.me/keysplit';

// Define custodians
const custodians = [
  { id: 'cust-1', name: 'Security Officer', role: 'primary' },
  { id: 'cust-2', name: 'CTO', role: 'executive' },
  { id: 'cust-3', name: 'External Auditor', role: 'auditor' },
];

// Create split config (2-of-3 threshold)
const config = { custodians, threshold: 2 };

// Split the root CA key
const keyData = {
  keyId: 'ROOT-CA-2026',
  keyType: 'root-ca',
  algorithm: 'RSA-4096',
  data: privateKeyBytes, // Uint8Array
  metadata: { purpose: 'Certificate authority root' }
};

const split = await splitKey(keyData, config);
if (!split.ok) throw new Error(split.error.message);

// Distribute split.value.shares[0] to cust-1, [1] to cust-2, [2] to cust-3...

// Later: reconstruct from any 2 shares
const shares = [split.value.shares[0], split.value.shares[2]];
const restored = await reconstructKey(shares);
if (!restored.ok) throw new Error(restored.error.message);

// restored.value => original Uint8Array (RSA-4096 key bytes)

That's it. Two function calls, two objects, and you have split key custody.

Section 04

Use Cases

Root Certificate Authority

A root CA's private key is the most critical key in an organization. One compromise can issue false certificates for the entire Internet. Split the root key across 5 custodians (security, CTO, legal, board representative, external auditor). Any 3 can perform root signing ceremonies. No single person can issue a certificate.

Regulated Financial Infrastructure

SEC, SOX, and PCI-DSS require key split custody for critical cryptographic operations. Keysplit enables compliance without expensive HSM deployments. Split encryption keys across 3 regional custodians (East, Central, West). Regional outage doesn't prevent key recovery from the other 2 regions.

Classified Government Systems

NIST FIPS 140-3 and EO 14028 demand multi-custodian controls. Split signal intelligence (SIGINT) encryption keys across 2-of-3 vaults (NSA, DOD, NRO). No single vault can decrypt archived classified communications.

Enterprise Key Lifecycle Management

Split keys for subordinate CAs, TLS certificates, and SAML signing keys. Store shares in geographically distributed vaults (e.g., AWS KMS, Azure Key Vault, on-premises HSM). One vault compromise doesn't leak the key.

Zero-Knowledge Authentication at Scale

Biometric systems require a master seed to derive per-verifier identifiers. Split the seed across custody tiers (device, server, escrow). No single system can derive all identities.

Blockchain and DeFi

Cryptocurrency exchanges and protocols use Keysplit to split hot-wallet signing keys across signatories. M-of-N multisig is transparent but costly. Keysplit enables private M-of-N semantics without on-chain overhead.

Section 05

Architecture

Keysplit's architecture is organized around three core operations: configuration validation, XorIDA splitting, and HMAC-verified reconstruction.

Split Pipeline

Step 1: Validation. Verify that the key is non-empty and the configuration is valid. A threshold of K requires at least K custodians. Reject threshold of 1 (no single-custodian keys).

Step 2: PKCS#7 Padding. Pad the key to a multiple of (nextOddPrime(N) - 1). This block size ensures XorIDA can work with arbitrary-length keys. Mandatory minimum of one byte padding, preventing padding oracle attacks.

Step 3: HMAC Integrity. Compute HMAC-SHA256 of the padded payload. Generate a random HMAC key. Distribute both the key and signature with each share. This enables post-reconstruction verification.

Step 4: XorIDA Split. Call splitXorIDA(padded, N, K) to generate N shares. Uses GF(2) arithmetic — no field inversion, no modular reduction, pure XOR operations.

Step 5: Package and Format. Each share is wrapped in a KeyShare object: base64-encoded data, HMAC signature, HMAC key, and metadata (keyId, custodianId, index, total, threshold). Data is formatted with the IDA5 branded header for provenance tracking (Xecret trademark, PRIVATE.ME mark, IDA5 magic, plaintext wrapper).

IDA5 Share Format

Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> Encrypted:// [base64 share data] => Generated by Xecret (TM)

This format is derived from US Patent 11,972,000 and must never be modified. The parser extracts data between "Encrypted://" and "=> Generated by Xecret".

Reconstruction Pipeline

Step 1: Validation. Verify that all shares have the same keyId, total, and threshold. Ensure the number of shares meets the threshold requirement.

Step 2: Extract Raw Data. Decode the base64 share data and strip the IDA5 header. Extract share indices from each KeyShare object.

Step 3: XorIDA Reconstruction. Call reconstructXorIDA(shares, indices, N, K). Returns the padded key bytes.

Step 4: HMAC Verification (FAIL CLOSED). Extract the HMAC key and signature from the first share. Verify the signature over the reconstructed padded payload. If verification fails, reject the entire result. Do not proceed to unpadding.

Step 5: PKCS#7 Unpadding. Strip the padding. If unpadding fails, reject.

Step 6: Return. Return the original key bytes.

HMAC Before Unpadding

Keysplit ALWAYS verifies the HMAC before unpadding. This is a fail-closed design: if shares are tampered with or corrupted, the signature check catches it before the key is returned. Never skip or delay HMAC verification.

Section 06

API Reference

splitKey()

Function signature
async function splitKey(
  key: CryptoKeyData,
  config: KeySplitConfig
): Promise<Result<KeySplitResult, KeySplitError>>

Splits a cryptographic key across custodians using XorIDA threshold sharing. Returns a Result with either a KeySplitResult (containing shares array) or a KeySplitError.

reconstructKey()

Function signature
async function reconstructKey(
  shares: readonly KeyShare[]
): Promise<Result<Uint8Array, KeySplitError>>

Reconstructs a cryptographic key from a threshold quorum of shares. Verifies HMAC integrity before returning. Returns a Result with either the original key bytes or an error.

Section 07

Type System

KeyType

Type definition
type KeyType = 'signing' | 'encryption' | 'root-ca' | 'tls';

Discriminator for cryptographic key purpose. Used for audit trails and custody policy enforcement. signing for Ed25519, ECDSA, RSA-PSS. encryption for AES, X25519. root-ca for root certificate authority keys. tls for TLS/SSL private keys.

CryptoKeyData

Interface definition
interface CryptoKeyData {
  readonly keyId: string;
  readonly keyType: KeyType;
  readonly algorithm: string;
  readonly data: Uint8Array;
  readonly metadata?: Readonly<Record<string, string>>;
}

A cryptographic key to be split. keyId is a user-supplied identifier (e.g., "ROOT-CA-2026"). data is the raw key bytes in Uint8Array format. metadata is optional and never encrypted; it's for audit trails and policy enforcement.

KeyCustodian

Interface definition
interface KeyCustodian {
  readonly id: string;
  readonly name: string;
  readonly role: string;
}

A custodian who holds a share of a split key. id is a unique identifier. role is a free-form string for policy (e.g., "primary", "executive", "auditor").

KeyShare

Interface definition
interface KeyShare {
  readonly keyId: string;
  readonly custodianId: string;
  readonly index: number;
  readonly total: number;
  readonly threshold: number;
  readonly data: string;
  readonly hmac: string;
  readonly hmacKey: string;
  readonly originalSize: number;
}

A single share of a split key. data, hmac, and hmacKey are all base64-encoded. originalSize is the size of the unpadded key in bytes (used for validation during reconstruction).

Section 08

Security Model

Information-Theoretic Security

Keysplit uses XorIDA (XorIDA over GF(2)) to split keys. This is not "hard to break"; it is mathematically impossible to break with fewer than K shares, regardless of computational power.

Formally: Given K-1 shares, an attacker cannot distinguish between two different keys that were split with the same configuration. Every possible key is equally consistent with the observed shares. This is the definition of information-theoretic security.

K-1 shares reveal 0 bits of information about the key
K shares uniquely determine the key

HMAC Integrity

Every share carries an HMAC-SHA256 signature computed over the padded key. The HMAC key is random and distributed with each share.

Verification happens before unpadding. If a share is tampered with (corrupted over the network, by a malicious custodian, or by disk bit-flip), the HMAC verification will fail during reconstruction. The operation fails closed — no partial key is returned.

No Trusted Third Party

Traditional key escrow requires a trusted escrow agent who encrypts and stores backup copies. Keysplit requires no such trust: a threshold quorum of custodians is sufficient. No single custodian can act unilaterally.

PKCS#7 Padding

Mandatory minimum of one byte padding prevents padding oracle attacks. Padding is verified through HMAC, not by side-channel timing.

Randomness

Keysplit uses only crypto.getRandomValues() for randomness. Math.random() is never called. Cryptographically strong randomness.

Share Indices Are Validated

XorIDA reconstruction requires that share indices be within the valid range [0, N). Out-of-range indices are rejected. Shares from different keys (different keyId) are rejected.

No Plaintext Logging

The original key material is never logged, printed, or sent to analytics. Only metadata (keyId, key type, algorithm, original size) is observable.

Section 09

Performance

Keysplit is fast. XorIDA operations on typical cryptographic keys (32–256 bytes) complete in microseconds. Larger keys (e.g., 4096-bit RSA = 512 bytes) take milliseconds.

Microbenchmarks (3-of-3 threshold)

Key Size Split Time Reconstruct Time Total
32 bytes (Ed25519) ~12 µs ~18 µs ~30 µs
64 bytes (P-521) ~22 µs ~35 µs ~57 µs
256 bytes (AES-256 + metadata) ~78 µs ~110 µs ~188 µs
512 bytes (RSA-4096) ~145 µs ~210 µs ~355 µs
2048 bytes (RSA-16384) ~580 µs ~840 µs ~1.42 ms

Times measured on Node.js 20 LTS (M1 MacBook Pro). Web Crypto operations (HMAC, digest) account for most time in typical scenarios; XorIDA itself is negligible for keys under 1KB.

Scaling

Time scales linearly with key size. Threshold (K) and custodian count (N) have minimal impact — both are small integers in practice. A 2-of-3 split takes the same time as a 5-of-7 split for the same key size.

No iteration cost. Unlike Shamir's Secret Sharing (which requires polynomial interpolation and modular arithmetic), XorIDA is pure XOR — all branches have identical cost, making it timing-attack resistant.

Section 10

Limitations

Shares Must Be Kept Confidential

A key is only as secure as its shares. Each share must be stored securely. If K shares are compromised, the key is compromised. Keysplit does not provide confidentiality for shares — it assumes each custodian stores their share in a secure location (HSM, encrypted storage, air-gapped machine).

Transport. Share delivery between custodians must use encrypted channels (TLS, or Xlink for M2M scenarios).

No Automatic Recovery

Keysplit does not provide automatic key recovery mechanisms. If a custodian loses their share, reconstruction requires the other custodians to retrieve their shares and coordinate with you. This is intentional — automatic recovery would require storing shares in a way that's accessible to the recovery mechanism, introducing new attack surface.

Share Indices Are Public

The share index (which position in the XorIDA split) is stored in plaintext in the KeyShare object. An attacker who observes all N shares knows which custodian held which share, but this is unavoidable in a practical system. What matters is that the key itself remains secure.

Metadata Is Not Encrypted

The metadata field on a KeyShare is not encrypted. Do not store sensitive information (private notes, location data) in metadata. Metadata is for operational purposes only (e.g., "Root CA 2026", "HSM backup").

No Forward Secrecy

If all N shares are ever stored in the same location or network, an attacker who accesses that location can reconstruct the key. Keysplit assumes custodians store shares in geographically or administratively separate locations. This is your responsibility.

Timestamp and Custody Chain Not Tracked

Keysplit doesn't track when a share was created or who held it at what time. For audit purposes, store this metadata separately. Keysplit itself provides no audit trail.

Section 11

Post-Quantum Security

Keysplit's core security (XorIDA) is unconditionally post-quantum-safe. But the keys you split may rely on algorithms that will be broken by quantum computers.

XorIDA Is Quantum-Safe

XorIDA works over GF(2) with pure XOR operations. There is no mathematical assumption (discrete log, factoring, lattice hardness) that could be broken by a quantum computer. The information-theoretic security holds even if quantum computers become practical.

Keys Themselves May Not Be

If you split an RSA-4096 key, Keysplit protects the key's privacy (fewer than K shares reveal nothing). But the key's security depends on the hardness of factoring 4096-bit numbers, which a sufficiently powerful quantum computer could break.

Solution: Use post-quantum algorithms for keys you intend to split. NIST PQC finalists (ML-KEM, ML-DSA, SLH-DSA) are suitable. The PRIVATE.ME platform already uses ML-KEM-768 and ML-DSA-65 for transport-layer encryption and signatures.

Or, split FIPS 140-3 approved keys (AES-256 for symmetric encryption, or hybrid ECC+PQC keypairs). Keysplit doesn't care what kind of key you split — it just protects the bits.

Recommendation

Best Practice

For new key generation, use post-quantum algorithms (ML-KEM for key exchange, ML-DSA or SLH-DSA for signing). Split them with Keysplit. You get both:

  • Information-theoretic security from Keysplit (unconditionally unbreakable)
  • Post-quantum resistant crypto from the key algorithm itself (defended against quantum computers)
Section 12

Integration & Deployment

Installation

Install via npm
pnpm add @private.me/keysplit

Environment Requirements

Platform Requirement Status
Node.js 20+ Web Crypto API available Supported
Deno 1.40+ Web Crypto available Supported
Bun 1.0+ Web Crypto available Supported
Browsers (Chromium 113+, Firefox 130+, Safari 17+) Ed25519 in Web Crypto Supported
Cloudflare Workers Web Crypto available Supported

Error Handling

All operations return a Result<T, KeySplitError> type. Check the ok field and use the error code for programmatic handling.

Error handling example
const result = await splitKey(key, config);
if (!result.ok) {
  switch (result.error.code) {
    case 'INVALID_KEY':
      // Handle empty or malformed key
      break;
    case 'THRESHOLD_EXCEEDS_CUSTODIANS':
      // Handle configuration error
      break;
    case 'SPLIT_FAILED':
      // Handle cryptographic failure
      break;
    default:
      // Handle unknown error
      break;
  }
  throw new Error(result.error.message);
}

Error Codes

Code Meaning Recoverable
INVALID_KEY Key data is empty or malformed Yes — provide a non-empty key
INVALID_CONFIG Configuration is malformed (bad threshold) Yes — adjust threshold/custodians
INSUFFICIENT_CUSTODIANS Fewer than 2 custodians configured Yes — add more custodians
THRESHOLD_EXCEEDS_CUSTODIANS Threshold K > number of custodians N Yes — lower threshold or add custodians
SPLIT_FAILED XorIDA split operation failed (rare) No — check key size and retry
HMAC_FAILURE Share HMAC verification failed during reconstruction No — share was tampered with or corrupted
RECONSTRUCTION_FAILED Reconstruction produced invalid data No — shares are inconsistent
INSUFFICIENT_SHARES Fewer shares provided than threshold requires Yes — provide more shares
SHARE_MISMATCH Shares belong to different keys Yes — provide shares from the same split

Production Deployment Example

A typical deployment for a root CA would:

  1. Generate the root CA key (RSA-4096 or ML-DSA).
  2. Call splitKey() with a 3-of-5 configuration (3 shares needed, 5 total custodians).
  3. Distribute each share to a custodian on a secure device (hardware security module, encrypted USB, or air-gapped machine).
  4. Store the share metadata (keyId, custodianId, index) in a secure database for audit purposes.
  5. When a certificate signing ceremony is needed, gather 3 custodians (any combination of the 5).
  6. Call reconstructKey() with their 3 shares to recover the root key in memory.
  7. Use the key to sign the certificate.
  8. Immediately discard the key from memory (no persisting to disk).
Security Note

Never persist the reconstructed key to disk or non-volatile storage. Use it in memory only, then discard. The entire point of split custody is that the full key never rests on a single machine.

Deployment Options

📦

SDK Integration

Embed directly in your application. Runs in your codebase with full programmatic control.

  • npm install @private.me/keysplit
  • TypeScript/JavaScript SDK
  • Full source access
  • Enterprise support available
Get Started →
🏢

On-Premise Upon Request

Enterprise CLI for compliance, air-gap, or data residency requirements.

  • Complete data sovereignty
  • Air-gap capable deployment
  • Custom SLA + dedicated support
  • Professional services included
Request Quote →

Enterprise On-Premise Deployment

While keySplit is primarily delivered as SaaS or SDK, we build dedicated on-premise infrastructure for customers with:

  • Regulatory mandates — HIPAA, SOX, FedRAMP, CMMC requiring self-hosted processing
  • Air-gapped environments — SCIF, classified networks, offline operations
  • Data residency requirements — EU GDPR, China data laws, government mandates
  • Custom integration needs — Embed in proprietary platforms, specialized workflows

Includes: Enterprise CLI, Docker/Kubernetes orchestration, RBAC, audit logging, and dedicated support.

Contact sales for assessment and pricing →