Skip to main content

Key Concepts

This page explains how Silent Shard Duo works: the components you run, the two signing parties, the storage that holds keyshares, key refresh, and the custody models. If you are new to MPC, start with the Introduction.

How the parties communicate

Silent Shard Duo is a two-party (2-of-2) wallet. There is no single private key stored on a device or a server. Instead, two parties run an interactive protocol together: the Duo SDK in your mobile app, and a second party: a Duo Server you deploy on your own infrastructure (see Duo Server), or a second user device.

MPC communication between the Duo Server and the mobile app

Running the protocol means exchanging a sequence of messages, called rounds, over a session (a WebSocket connection between the parties). In each round, a party performs a local computation on its own secret and sends the result to the other party. Neither party ever reveals its secret, and the full private key is never formed anywhere.

After the key-generation rounds finish, each party holds its own keyshare:

  • Share A: on the user's device.
  • Share B: on the second party.

Together the two shares define one wallet, and its public key (the on-chain address) is available immediately. Every later operation (sign, refresh, export) runs as another exchange of rounds between the two parties.

Signing

To sign, the parties run a signing exchange: each contributes a partial computation from its own share alone, and the results combine into a single, standard signature over the message hash. Because the private key is never reconstructed, one party alone cannot sign: an attacker who compromises a single share cannot produce a signature.

Key refresh

Key refresh replaces both shares with new ones for the same wallet. The address does not change, but the previous shares no longer match the new ones, so they are invalidated and can no longer be used for signing.

Other operations

Beyond keygen, sign, and refresh, the SDK covers the rest of a wallet's lifecycle:

  • BIP32 derivation: derive child keys from a wallet along a derivation path, so one wallet can produce many addresses.
  • Import key: bring an existing private key into an MPC wallet by splitting it into shares. Because the key existed in full beforehand, this does not carry the same "never assembled" guarantee as a generated wallet.
  • Export key: reconstruct and export the full private key by combining the shares, for moving a wallet out of MPC. Gate this behind strong user authentication.
  • Verifiable backup: produce an encrypted, verifiable backup of a keyshare that can be restored later, without exposing the key.

The storage client

The SDK never holds keyshares itself. It reads and writes them through a storage client that you provide, which lets the SDK create, read, and update keyshares on the client side.

The SDK ships SimpleStorageClient, an in-memory implementation for tests and development; keyshares held there are lost on restart. Production apps supply a persistent one (see Custom storage client).

Reconcile vs. no-reconcile

Because keyshares live in the storage client, creating one is a two-step process. When a new share is generated (during keygen or refresh), the SDK first creates it in storage with a Pending state, then commits it by updating that record to a Committed state. Only a committed keyshare is the wallet's live share, and how the commit happens is the difference between the two modes.

  • Reconcile (default). After generation, both parties hold a Pending keyshare. They run one extra round of communication to confirm they generated matching shares, and then update them to Committed. Neither side commits a share the other didn't agree to, so the two parties cannot diverge.

  • No-reconcile. There is no extra round: the server commits its share directly, and the mobile app commits (updates its stored keyshare to Committed) too. This is acceptable for keygen, but riskier for key refresh: the server commits the new share immediately, so if the client fails to save and commit the newly generated share, the two sides diverge (server on the new share, client still on the old one). In no-reconcile, persisting the new keyshare is the client's responsibility.

Custody models

The protocol is the same 2-of-2 in both setups; what differs is who holds share B.

Mobile + Server (semi-custody)

One share on the user's device, the other on your Duo Server. This is the common setup: it supports provider-assisted recovery and lets the user operate from a single device.

Loading Diagram...
  • The provider co-signs only after authenticating the user.
  • The provider can offer account recovery.
  • The provider can enforce policies such as fraud checks or spending limits.

Mobile + Mobile (self-custody)

Both shares live on user-controlled devices, coordinated through a relay. No third party can access a share.

Loading Diagram...
  • The user keeps full control of both shares.
  • Shares never leave user-controlled devices.
  • No service provider can block a signature.

Transport security

Messages exchanged between the parties are end-to-end encrypted. See the Security Model for the guarantees and threat model.

Next steps