BridgeVault: Cross-Chain Bridge Security
DeFi cross-chain bridge signing key protection via XorIDA threshold sharing. Split bridge signing keys across independent validator nodes so that no single validator holds complete key material. Reconstruction requires a configurable threshold of cooperating validators, providing cryptographic guarantees that any subset below threshold reveals zero information about the key.
Executive Summary
Cross-chain bridges are among the most attacked targets in DeFi. A single compromised signing key can drain the entire bridge. BridgeVault eliminates this single point of failure.
Billions of dollars have been lost to bridge exploits where an attacker obtained control of a hot wallet or a majority of multisig keys held by a small validator set. Traditional multisig schemes require coordination among validators to approve each transaction, creating operational bottlenecks and still allowing key material to exist in complete form during signing ceremonies.
BridgeVault uses XorIDA (threshold sharing over GF(2)) to split bridge signing keys across independent validator nodes. No single validator holds the complete key material. Reconstruction requires a configurable threshold of cooperating validators, and any subset below that threshold reveals mathematically zero information about the original key — not computationally hard to break, but information-theoretically impossible.
Two functions cover the complete workflow: splitBridgeKey() takes a bridge signing key and configuration, splits it across validators using XorIDA, and returns integrity-protected shares with HMAC-SHA256. reconstructBridgeKey() takes a threshold number of shares, verifies HMACs, and reconstructs the original key. The entire process completes in under 1ms for typical key sizes.
The Problem
Cross-chain bridges hold billions in total value locked (TVL) and are attractive targets for sophisticated attackers. Current security models create unacceptable single points of failure.
Bridge Exploits Are Catastrophic
Ronin Bridge (2022): $625M stolen. Attackers compromised 5 of 9 validator keys. The bridge required only 5 signatures to approve transactions. Once the threshold was reached, the entire bridge was drained in a single attack.
Wormhole Bridge (2022): $325M stolen. A single signature verification bug allowed an attacker to mint unauthorized tokens. The entire bridge was at risk from a single point of failure.
Poly Network (2021): $611M stolen (later returned). The attacker gained control of the bridge's signing keys and transferred funds to their own addresses. The entire system depended on key security.
Traditional Multisig Is Insufficient
Most bridges use multisig wallets where a threshold of validators (e.g., 5-of-9) must sign to approve a transaction. This creates three problems:
1. Key material exists in complete form. Each validator holds their complete private key. Compromise of a threshold number of validators means complete control of the bridge. The keys exist, they can be stolen.
2. Social engineering and coercion. Attackers can target individual validators through phishing, malware, insider threats, or physical coercion. Small validator sets are especially vulnerable.
3. Operational complexity. Every transaction requires coordination among multiple parties. Validators must be online, reachable, and responsive. This creates latency and potential availability failures.
| Property | Single Key | Traditional Multisig | BridgeVault |
|---|---|---|---|
| Complete key exists | Yes (1 location) | Yes (threshold locations) | Never |
| Single point of failure | Yes | Reduced (threshold) | No |
| Info-theoretic security | No | No | Yes (XorIDA) |
| Sub-threshold reveals | Everything | Nothing (trust-based) | Mathematically zero |
| HMAC integrity | No | Varies | SHA-256 on every share |
| Reconstruction latency | Instant | Coordination required | <1ms (typical) |
How BridgeVault Works
XorIDA threshold sharing over GF(2) splits bridge signing keys into shares distributed across validators. No validator sees the complete key. Reconstruction requires exactly the configured threshold.
The Split Operation
A bridge operator generates a signing key (Ed25519, ECDSA, or any key material up to several KB). This key controls token transfers across chains. Instead of storing it in a hot wallet or distributing complete copies to validators, the operator uses BridgeVault to split it:
import { splitBridgeKey } from '@private.me/bridgevault'; const bridgeKey = { keyId: 'KEY-ETH-POLYGON-001', bridgeId: 'BRIDGE-ALPHA', chainPair: 'ETH-POLYGON', keyData: new Uint8Array([/* 32-byte Ed25519 key */]), createdAt: Date.now(), }; const config = { validators: [ { id: 'val-alpha', name: 'Validator Alpha', stake: '1000000' }, { id: 'val-beta', name: 'Validator Beta', stake: '750000' }, { id: 'val-gamma', name: 'Validator Gamma', stake: '500000' }, ], threshold: 2, // Require 2-of-3 to reconstruct }; const result = await splitBridgeKey(bridgeKey, config); // result.shares contains one BridgeShare per validator // Each share includes HMAC-SHA256 for integrity verification
Each validator receives a share containing their portion of the key material, their validator ID, the share index, and an HMAC for integrity verification. The shares are mathematically independent — any single share (or any subset below threshold) reveals zero information about the original key.
The Reconstruction Operation
When the bridge needs to sign a transaction, it collects shares from a threshold number of validators and reconstructs the original key:
import { reconstructBridgeKey } from '@private.me/bridgevault'; // Collect shares from threshold validators (2-of-3 in this example) const shares = [shareFromAlpha, shareFromBeta]; const result = await reconstructBridgeKey(shares); if (result.ok) { const originalKey = result.value; // Uint8Array identical to original // Use originalKey to sign the bridge transaction // Then immediately discard the key from memory }
Reconstruction verifies HMAC integrity on every share before processing. If any share has been tampered with, reconstruction fails immediately. The reconstructed key is identical to the original and can be used for a single signing operation before being discarded.
Real-World Use Cases
Six scenarios where BridgeVault protects bridge signing keys from single points of failure.
Split the master signing key for ETH-Polygon bridge across 5 validators with 3-of-5 threshold. Any two validators can be compromised or offline without exposing the key or halting operations.
3-of-5 thresholdOptimistic and ZK-rollup bridges require signing withdrawal proofs. Split sequencer signing keys across geographically distributed validators to eliminate single-region failure risk.
Geographic distributionCross-chain liquidity pools hold massive TVL. Split pool management keys across independent validators from different organizations to prevent insider compromise.
Organizational independenceRegulated institutions require cryptographic proof that no single employee can access bridge keys. BridgeVault provides mathematical guarantee that threshold cooperation is required.
Compliance + auditabilityDecentralized governance over bridge keys. Split keys across elected validators with on-chain threshold voting. Key material never exists in single location, even during upgrades.
On-chain threshold governanceIf a validator is compromised, generate a new key, split it, and distribute new shares to remaining validators. The compromised validator learns nothing from their old share.
Zero-knowledge rotationArchitecture
BridgeVault is built on @private.me/crypto's XorIDA threshold sharing. Two primary functions, five core types, and eight error codes cover the complete API surface.
System Components
Split/Reconstruct Flow
Integration Guide
Add BridgeVault to an existing bridge in three steps: install, split keys, implement threshold signing.
Step 1: Installation
pnpm add @private.me/bridgevault
Peer dependencies: @private.me/crypto, @private.me/shared. These are automatically resolved in monorepo environments.
Step 2: Split Existing Bridge Keys
import { splitBridgeKey } from '@private.me/bridgevault'; // Load your existing bridge signing key (Ed25519, ECDSA, etc.) const existingKeyBytes = loadBridgeKey('ETH-POLYGON'); const bridgeKey = { keyId: 'KEY-ETH-POLYGON-001', bridgeId: 'YOUR-BRIDGE-ID', chainPair: 'ETH-POLYGON', keyData: existingKeyBytes, createdAt: Date.now(), }; // Define your validator set and threshold const config = { validators: [ { id: 'validator-1', name: 'Primary Node', stake: '5000000' }, { id: 'validator-2', name: 'Backup Node', stake: '3000000' }, { id: 'validator-3', name: 'Failover Node', stake: '2000000' }, ], threshold: 2, // 2-of-3 required }; const result = await splitBridgeKey(bridgeKey, config); if (!result.ok) { console.error('Split failed:', result.error); return; } // Distribute shares to validators over secure channels for (const share of result.value.shares) { await distributeShareToValidator(share.validatorId, share); } // CRITICAL: Securely delete the original key from all locations securelyEraseKey(existingKeyBytes);
Step 3: Implement Threshold Signing
import { reconstructBridgeKey } from '@private.me/bridgevault'; // When a bridge transaction needs signing: async function signBridgeTransaction(txData) { // 1. Request shares from threshold validators const shares = await collectSharesFromValidators( ['validator-1', 'validator-2'], // Any 2 of 3 'KEY-ETH-POLYGON-001' ); // 2. Reconstruct the signing key (verifies HMACs automatically) const result = await reconstructBridgeKey(shares); if (!result.ok) { throw new Error(`Reconstruction failed: ${result.error.code}`); } // 3. Use the reconstructed key for signing const signingKey = result.value; const signature = await signWithKey(signingKey, txData); // 4. CRITICAL: Immediately purge the key from memory signingKey.fill(0); // Zero out the buffer return signature; }
Security Properties
BridgeVault provides information-theoretic security guarantees that go beyond computational assumptions. The security model is mathematically provable.
Information-Theoretic Security
Traditional encryption (AES, RSA, ECC) is computationally secure: breaking it requires solving a hard mathematical problem. Given unlimited computing power, these systems can theoretically be broken. XorIDA threshold sharing is information-theoretically secure: any subset of shares below the threshold reveals zero information about the original key, even with infinite computing power.
This is not a claim about difficulty — it is a mathematical impossibility. An attacker who compromises K-1 validators in a K-of-N threshold system learns nothing. The missing share could be any value, and all values are equally likely. There is no ciphertext to attack, no key to crack, no problem to solve.
HMAC Integrity Verification
Every share includes an HMAC-SHA256 tag computed over the share data. Before reconstruction, BridgeVault verifies the HMAC on every provided share. Tampered or corrupted shares are detected and rejected before any computation occurs. An attacker cannot modify share data without breaking HMAC-SHA256.
Security Against Common Attacks
| Attack Vector | Traditional Multisig | BridgeVault |
|---|---|---|
| Compromise single validator | Partial key exposure (1-of-N) | Zero information revealed |
| Compromise sub-threshold validators | Partial key exposure (K-1 keys) | Information-theoretically zero |
| Tamper with share data | Varies by implementation | HMAC verification fails |
| Social engineering validator | Steal complete private key | Only one share stolen, useless alone |
| Insider threat (single validator) | Full private key access | No key material to steal |
| Quantum computer | Eventually vulnerable (RSA, ECDSA) | Quantum-proof (IT security) |
Random Number Generation
All random bytes are generated via crypto.getRandomValues() from the Web Crypto API. No use of Math.random() anywhere in the codebase. This is a hard requirement inherited from @private.me/crypto.
Memory Safety
Reconstructed keys exist only in memory for the duration of the signing operation. They are never written to disk, never logged, and immediately zeroed out after use. JavaScript does not provide guaranteed memory erasure, but the best-effort pattern is keyBuffer.fill(0) followed by allowing the buffer to go out of scope for garbage collection.
Benchmarks
Performance characteristics measured on Node.js 22, Apple M2. All operations complete in under 1ms for typical bridge signing keys.
| Operation | Time | Notes |
|---|---|---|
| Split 32-byte Ed25519 key (3 shares) | <1ms | XorIDA split + HMAC-SHA256 per share |
| Split 64-byte ECDSA key (5 shares) | <1ms | Linear scaling with share count |
| Reconstruct 32-byte key (2-of-3) | <1ms | HMAC verification + XorIDA reconstruction |
| Reconstruct 64-byte key (3-of-5) | <1ms | Typical bridge key size |
| HMAC-SHA256 verification | <0.5ms | Per share, Web Crypto API |
| SHA-256 key hash | <0.5ms | For audit trail |
| Full split-distribute-collect-reconstruct | <5ms | Including network latency simulation |
Honest Limitations
BridgeVault solves the single-point-of-failure problem for bridge signing keys, but it is not a complete solution to all bridge security concerns. Here is what it does NOT do.
1. Does Not Prevent Threshold Collusion
If a threshold number of validators collude or are coerced, they can reconstruct the key and sign unauthorized transactions. BridgeVault raises the bar from compromising one validator to compromising K validators, but it does not eliminate the risk entirely. Mitigation: choose validators from independent organizations, jurisdictions, and infrastructure providers.
2. Does Not Protect the Reconstruction Environment
The reconstructed key exists in plaintext in the memory of the process that performs reconstruction. If that environment is compromised (malware, side-channel attacks, memory dumps), the key is exposed. BridgeVault protects keys at rest and in distribution, not during active use. Mitigation: run reconstruction in a trusted execution environment (TEE) or hardware security module (HSM).
3. Does Not Provide Consensus or Voting
BridgeVault is a key management system, not a consensus protocol. It does not decide which transactions are valid or enforce voting rules among validators. You still need separate logic to determine when reconstruction should happen and which validators are authorized. Mitigation: integrate with existing bridge governance and consensus mechanisms.
4. Does Not Prevent Smart Contract Exploits
If the bridge's smart contracts have vulnerabilities (reentrancy, logic errors, signature replay), BridgeVault does not protect against those. Threshold key management only protects the signing key itself. Mitigation: audit smart contracts, use formal verification, implement time-locks and circuit breakers.
5. Requires Threshold Validators to Be Online
To reconstruct a key, you need exactly K validators to provide their shares. If fewer than K validators are reachable, reconstruction fails and the bridge cannot process transactions. Higher thresholds provide stronger security but reduce availability. Mitigation: choose N and K to balance security and fault tolerance (e.g., 3-of-5 allows 2 validators to be offline).
6. Share Distribution Is Your Responsibility
BridgeVault splits keys into shares and reconstructs them, but it does not distribute shares to validators or manage validator authentication. You are responsible for secure channels, validator identity verification, and access control. Mitigation: use TLS mutual authentication, DID-based identity, or hardware tokens for validator authentication.
Deployment
BridgeVault is distributed as a TypeScript/JavaScript package for integration into existing bridge validator infrastructure. Install via npm and integrate directly into your bridge logic.
Package Installation
# Install the BridgeVault package npm install @private.me/bridgevault # Or with pnpm pnpm add @private.me/bridgevault # Or with yarn yarn add @private.me/bridgevault
TypeScript Integration
import { splitBridgeKey, reconstructBridgeKey } from '@private.me/bridgevault'; import type { BridgeKey, BridgeConfig, BridgeShare } from '@private.me/bridgevault'; // Split a bridge signing key across validators const result = await splitBridgeKey(bridgeKey, config); if (result.ok) { // Distribute shares to validator nodes for (const share of result.value.shares) { await distributeToValidator(share.validatorId, share); } }
Environment Setup
# BridgeVault has zero configuration and zero external dependencies # All cryptographic operations use Web Crypto API (browser) or crypto module (Node.js) # No API keys, no network calls, no external services
API Reference & Error Codes
Complete function signatures, types, and error taxonomy for integration.
Full API Surface
Two primary functions and five core types define the complete public API.
Functions
Splits a bridge signing key across validator nodes using XorIDA threshold sharing. Returns a BridgeSplitResult containing one share per validator, each with HMAC-SHA256 integrity protection, or a BridgeError if validation fails.
Reconstructs the original bridge signing key from a threshold number of validator shares. Verifies HMAC integrity on every share before reconstruction. Returns the original key as Uint8Array or a BridgeError if verification or reconstruction fails.
Types
interface BridgeKey { readonly keyId: string; // Unique identifier for this key readonly bridgeId: string; // Bridge identifier (e.g., 'ETH-POLYGON') readonly chainPair: string; // Chain pair (e.g., 'ETH-POLYGON') readonly keyData: Uint8Array; // The signing key bytes readonly createdAt: number; // Timestamp (ms since epoch) } interface Validator { readonly id: string; // Validator unique ID readonly name: string; // Human-readable name readonly stake: string; // Stake amount (for PoS selection) } interface BridgeConfig { readonly validators: readonly Validator[]; // Validator set readonly threshold: number; // K in K-of-N } interface BridgeShare { readonly keyId: string; // Must match original key readonly validatorId: string; // Validator that owns this share readonly index: number; // Share index (0-based) readonly total: number; // Total number of shares readonly threshold: number; // Required for reconstruction readonly data: string; // Base64-encoded share data readonly hmac: string; // HMAC-SHA256 hex string readonly originalSize: number; // Original key size in bytes } interface BridgeSplitResult { readonly keyId: string; // Key identifier readonly shares: readonly BridgeShare[]; // One per validator readonly keyHash: string; // SHA-256 of original key }
Error Taxonomy
Eight error codes cover all failure modes. Every error includes a machine-readable code and human-readable message.
| Code | Description |
|---|---|
| INVALID_KEY | Bridge key data is malformed or empty. Check that keyData is a non-empty Uint8Array. |
| INVALID_CONFIG | Configuration is invalid. Common causes: threshold < 2, threshold > validator count, or threshold > total shares. |
| INSUFFICIENT_VALIDATORS | Fewer than 2 validators provided. At minimum, 2 validators are required for threshold sharing. |
| SPLIT_FAILED | XorIDA split operation failed. This is an internal error indicating a problem with the crypto library. |
| HMAC_FAILURE | HMAC-SHA256 integrity check failed during reconstruction. One or more shares have been tampered with or corrupted. |
| RECONSTRUCTION_FAILED | XorIDA reconstruction produced invalid output. This may indicate incompatible shares or internal crypto failure. |
| INSUFFICIENT_SHARES | Fewer shares provided than the required threshold. Check that you are collecting at least K shares for K-of-N reconstruction. |
| INVALID_SHARE | Share data is malformed or inconsistent. Common causes: mismatched keyId, duplicate share indices, or corrupted share structure. |
const result = await reconstructBridgeKey(shares); if (!result.ok) { switch (result.error.code) { case 'INSUFFICIENT_SHARES': console.error('Not enough shares. Need', threshold, 'got', shares.length); break; case 'HMAC_FAILURE': console.error('Share tampering detected!'); break; case 'INVALID_SHARE': console.error('Share data is corrupted or incompatible'); break; default: console.error('Unknown error:', result.error); } return; }