MPC Wallet Development
A traditional crypto wallet stores the private key in one place: on a device, in an HSM, in the cloud. Any compromise of that location = loss of funds. MPC (Multi-Party Computation) solves the fundamental problem differently: the private key never exists as a whole in any single point of the system. Instead, multiple parties hold key shares and jointly compute a signature without revealing their shares to each other.
This is not multisig. In multisig, transaction signatures require M out of N signatures, each visible on-chain — the network knows multisig is being used. In MPC, the final signature looks like an ordinary ECDSA signature of a single key. No on-chain overhead, no protocol changes. This is critical for: reducing gas costs, privacy (hides key management scheme), compatibility with any chain and dApp.
Mathematical Foundation
Shamir's Secret Sharing and Threshold Schemes
The foundation of MPC wallets is threshold signature schemes (TSS). Most commonly used: GG18, GG20 (Gennaro-Goldfeder), CGGMP21, and DKLS19.
Shamir's Secret Sharing — is a basic concept, but not TSS itself. In SSS, a secret is divided into N shards, M of N is sufficient for recovery. The problem: recovery requires collecting shards in one place — a vulnerability. TSS eliminates this: the signature is computed without assembling the key.
Threshold ECDSA (using secp256k1 as in Bitcoin/Ethereum):
Let the private key be d = d1 + d2 (mod q) for a 2-of-2 scheme. Each party holds d1 and d2. During signing:
1. Each party generates its own nonce: k1, k2
2. Jointly compute R = (k1 + k2)^(-1) * G (commitment protocol)
3. Each party computes its part s: s1, s2
4. Final signature: s = s1 + s2 (mod q)
5. Signature (r, s) — a normal ECDSA signature
The complexity is in step 2: direct computation would require revealing k1 or k2. Therefore, Oblivious Transfer, Paillier encryption, or Curve25519-based protocols are used for secure computation.
Protocols: GG20 vs CGGMP21
GG20 (Gennaro-Goldfeder 2020) — was the de facto standard for a long time. Used in Fireblocks, ZenGo, Coinbase Wallet. Supports threshold t-of-n for arbitrary t and n. Requires Paillier encryption for secure multiplication.
GG20 drawbacks: implementation complexity, expensive keygen (O(n²) communications), vulnerability to "rogue key attack" requires range proofs that increase message sizes.
CGGMP21 (Canetti-Gennaro-Goldfeder-Makriyannis-Peled 2021) — current state-of-the-art. Fixes GG20 vulnerabilities, more efficient signing (fewer communication rounds). Supports identifiable abort — if one party misbehaves, it can be identified through cryptographic proof.
DKLS19 — an alternative based on Oblivious Transfer. More compact messages, but fewer production implementations.
Key Refresh
A critically important operation: periodic update of key shares without changing the public key (and thus without changing the address). If an attacker compromised one shard but didn't manage to obtain the final signature before refresh — the compromise is neutralized.
Refresh protocol (simplified):
1. Each party generates new random shares: r1, r2, ...rn
2. They sum: Σri = 0 (zero net change)
3. Each party adds its ri to the current di
4. Public key d*G does not change: Σ(di + ri)*G = d*G + Σri*G = d*G
Recommended refresh frequency: every 30-90 days, or if any participant's compromise is suspected.
Production MPC Wallet Architecture
Typical 2-of-3 Scheme for Mobile Wallet
┌──────────────────────────────────────────────────────┐
│ User Device (Mobile) │ Company Server │ Backup │
│ Share 1 (locally, │ Share 2 │ Share 3 │
│ encrypted with │ (HSM/TEE) │ (MPC │
│ biometry) │ │ backup) │
└──────────────────────────────────────────────────────┘
Signing: Device + Server (2-of-3)
Recovery: Device + Backup or Server + Backup
User loses phone → recovery via Server + Backup shards. Server is hacked → no chance without Device or Backup. This is the model of ZenGo and similar non-custodial MPC wallets.
System Components
Key generation service. Implements DKG (Distributed Key Generation) protocol among participants. Result: each participant receives their share, no one knows the full key. Implementations: tss-lib (Binance, Go), multi-party-ecdsa (ZenGo, Rust), threshold-sig-lib (Fireblocks internal).
// ZenGo's curv + tss-lib example (Rust)
use curv::elliptic::curves::{Secp256k1, Point, Scalar};
use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::party_i::*;
// Phase 1: each party generates a commitment
let party1_keys = Keys::create(1);
let (commit1, decom1) = party1_keys.phase1_broadcast_phase3_proof_of_correct_key();
// Phase 2: commitment exchange, VSS computation
// Phase 3-5: verification and share finalization
// Result: party1_keys.u_i — party 1's private share
Signing service. Orchestrates signing sessions among participants. Must support: concurrent sessions (multiple transactions in parallel), timeout handling (if a participant doesn't respond), session ID for message correlation.
Communication layer. Encrypted P2P channel among participants. TLS + additional end-to-end encryption of protocol messages. Cannot use unencrypted channel: intermediate messages contain partial values that when accumulated could leak the share.
HSM/TEE integration. Server share is stored in HSM (AWS CloudHSM, Thales) or TEE (Intel SGX, ARM TrustZone). Critical: operations with the share are performed inside the protected environment, the share never leaves into open memory. Azure Key Vault Managed HSM and AWS CloudHSM support custom key operations via PKCS#11 interface.
Recovery Protocol
A crucial UX aspect: how the user recovers access without a seed phrase.
Social recovery MPC. Backup share is encrypted with keys of trusted persons (guardians). To recover, consent from M out of N guardians is needed. Implementation: backup share is encrypted via threshold encryption for the guardian set. A guardian can be: another user device, email service (via KMS), trusted friend (via their public key), recovery service.
KMS-based backup. Backup share is encrypted via user's KMS key. To recover: pass KYC/authentication via KMS provider → decrypt backup share → perform re-sharing with the new device share.
Chain Support: Multi-Curve MPC
Different blockchains use different elliptic curves:
| Chain | Curve | Signature Algorithm |
|---|---|---|
| Ethereum, Bitcoin | secp256k1 | ECDSA |
| Solana, Cardano | ed25519 | EdDSA |
| Cosmos | secp256k1 + ed25519 | both |
| StarkNet | STARK curve | Schnorr-like |
| Aptos, Sui | ed25519 | EdDSA |
TSS for ed25519 differs from secp256k1: uses a scheme based on Schnorr signatures (FROST protocol — Flexible Round-Optimized Schnorr Threshold). FROST is simpler to implement, more efficient in communication. For production multi-chain wallets, support for both is needed.
Hierarchical Deterministic (HD) in MPC context. Classic BIP32 cannot be applied directly: no single seed. Solution: threshold BIP32 — each party stores their share for the master private key, child key derivation is performed via MPC operations or by storing separate shares for each derived path (less efficient, but simpler).
Security and Audit
Attack Vectors
Malicious party in signing protocol. A participant may try to obtain information about others' shares through anomalous messages. Protection: range proofs, zero-knowledge proofs of correctness for each intermediate value. CGGMP21 was specifically designed with identifiable abort: the protocol can prove which party is misbehaving.
Replay attack on signing sessions. Intercepted messages from one signing session should not be used in another. Protection: session ID is included in every message, sessions are one-time.
Side-channel via timing. Implementations in Java/Python are vulnerable to timing attacks on operations with large numbers. Production implementations must use constant-time arithmetic (library ct-codecs, Rust subtle crate).
Compromised communication channel. TLS with certificate pinning + additional authenticated encryption at the protocol level (each MPC message is signed with the sender's long-term key).
Audit Recommendations
The MPC protocol is a cryptographically complex component. An audit should include:
- Verification of correct implementation of the specific protocol (GG20/CGGMP21) against the paper
- Side-channel resistance analysis
- Fuzz testing signing sessions with anomalous messages
- Verifiable key generation (public key matches expected)
Providers for MPC audits: NCC Group, Kudelski Security, specialize in cryptographic implementations.
Ready-Made Libraries vs Custom Implementation
| Library | Language | Protocol | Production Use |
|---|---|---|---|
| tss-lib (Binance) | Go | GG18/GG20 | Binance DEX |
| multi-party-ecdsa (ZenGo) | Rust | GG20/CGGMP21 | ZenGo Wallet |
| threshold-bls (dfinity) | Rust | threshold BLS | Internet Computer |
| FROST (ZKCrypto) | Rust | FROST (ed25519) | Zcash |
| Web3Auth MPC SDK | TS/SDK | CGGMP21 | SaaS |
Recommendation: for most projects — integrate with Web3Auth MPC Core Kit or Fireblocks MPC SDK instead of building from scratch. Custom implementation of the MPC protocol requires deep expertise in applied cryptography and takes 6–12 months. A mistake in MPC implementation = potential leak of users' private keys.
Development Stages
| Phase | Content | Duration |
|---|---|---|
| Architecture | Choose protocol, share storage scheme, recovery model | 2 weeks |
| Core MPC | Keygen, signing, key refresh (based on existing library) | 4–8 weeks |
| HSM/TEE integration | Server share in protected environment | 2–4 weeks |
| Chain support | Multi-curve, HD derivation | 2–4 weeks |
| Recovery flows | Social recovery or KMS backup | 2–4 weeks |
| Security audit | Cryptographic + code review audit | 4–6 weeks |
| Mobile/Web SDK | SDK for integration into application | 3–5 weeks |
Minimum production-ready MPC wallet (2-of-2, one chain, basic recovery) — 4–5 months. Full-featured multi-chain with social recovery and HSM — 8–12 months.







