How ECDSA Pre-Parameters Are Generated and Cached for Performance in MPc-IUM

The MPc-IUM node generates ECDSA pre-parameters once during initial startup, persists them to a Badger-backed KV store, and reuses the cached values for all subsequent MPC sessions to eliminate expensive regeneration overhead.

The fystack/mpcium repository implements a high-performance multi-party computation (MPC) node that eliminates redundant cryptographic work by caching ECDSA pre-parameters. This analysis explores the exact mechanism—found in pkg/mpc/node.go—where the node generates these parameters during first-time initialization, stores them persistently, and injects them into key generation, signing, and resharing workflows.

Generation and Caching Mechanism

When a node is instantiated via NewNode (lines 55‑71 in pkg/mpc/node.go), it immediately invokes node.generatePreParams() to ensure cryptographic material is ready before processing MPC requests.

First-Time Generation with Timeout

The generatePreParams method iterates over two indexes (i = 0,1) to prepare dual parameter sets. For each index, it attempts to read a cached value from the KV store using the key pre_params_i (lines 23‑30). If the key is absent, the node invokes the underlying keygen.GeneratePreParams function from the tss-lib library with a 5‑minute timeout, marshals the resulting *keygen.LocalPreParams struct to JSON, and writes it back to the store (lines 33‑48).

// Simplified flow from pkg/mpc/node.go
func (n *Node) generatePreParams() error {
    for i := 0; i < 2; i++ {
        key := fmt.Sprintf("pre_params_%d", i)
        // Attempt to load from Badger-backed KV store
        data, err := n.kvStore.Get(key)
        if err == nil {
            // Unmarshal cached data
            continue
        }
        // Generate with 5-minute timeout if cache miss
        params, err := keygen.GeneratePreParams(timeout)
        // Marshal and store for future reuse
        jsonData, _ := json.Marshal(params)
        n.kvStore.Set(key, jsonData)
    }
    return nil
}

Persistent Storage Strategy

Because the KV store is backed by Badger (implemented in pkg/kvstore/badger.go), the JSON-encoded pre-parameters survive node restarts. On every subsequent startup, generatePreParams locates the stored blobs, unmarshals them into *keygen.LocalPreParams structs, and stores them in the node’s field ecdsaPreParams []*keygen.LocalPreParams (lines 38‑40). This skips the computationally expensive generation step entirely during routine restarts.

Version-Aware Selection for Resharing

For resharing sessions, the node must handle key versioning gracefully. The implementation maintains two distinct pre-parameter sets to support alternating requirements. When creating a resharing session, the code selects the appropriate entry via modulo arithmetic: p.ecdsaPreParams[version%2] (lines 351‑359 in pkg/mpc/node.go). This ensures that version 0 uses the first cached parameter set while version 1 uses the second, preventing state collisions during threshold key resharing operations.

Integration with MPC Sessions

All ECDSA-related sessions receive pre-parameters directly from the cached slice, typically defaulting to the first entry (p.ecdsaPreParams[0]).

Key Generation Sessions (lines 15‑18): The ecdsaKeyGenSession constructor receives the cached parameters immediately upon session creation.

Signing Sessions (lines 92‑96): When CreateSigningSession is invoked, the node passes node.ecdsaPreParams[0] to the underlying ecdsaSignSession, ensuring the expensive setup phase is never repeated per transaction.

// Example: Node instantiation triggers automatic pre-param caching
node := mpc.NewNode(
    "node-1",
    []string{"node-2", "node-3"},
    pubSub,          // messaging.PubSub implementation
    direct,          // messaging.DirectMessaging implementation
    kvstore,         // persistent Badger-backed KV store
    keyinfoStore,
    peerRegistry,
    identityStore,
    ckd,
)

// Create signing session—reuses cached pre-params automatically
session, err := node.CreateSigningSession(
    mpc.SessionTypeECDSA,
    "wallet-abc",
    "tx-123",
    "network-1",
    resultQueue,
    []uint32{44, 60},
    "idempotent-key",
)

Summary

  • One-time generation: generatePreParams in pkg/mpc/node.go creates pre-parameters only on first startup or cache miss, using a 5‑minute timeout for safety.
  • Persistent caching: Badger-backed KV store retains JSON-encoded parameters under keys pre_params_0 and pre_params_1, enabling instant reuse across node restarts.
  • Dual-set strategy: Two pre-parameter sets are maintained to support version-aware resharing via version%2 indexing.
  • Zero-cost sessions: Key generation, signing, and resharing sessions receive cached parameters directly, eliminating regeneration overhead for every MPC operation.

Frequently Asked Questions

What are ECDSA pre-parameters in MPc-IUM?

ECDSA pre-parameters are cryptographic values generated by the keygen.GeneratePreParams function from the tss-lib library. In fystack/mpcium, these are expensive-to-compute structures required to initialize MPC sessions for threshold ECDSA key generation, signing, and resharing.

How does the caching mechanism improve performance?

By generating pre-parameters once and storing them in a Badger-backed KV store (as implemented in pkg/kvstore/badger.go), the node avoids calling the CPU-intensive GeneratePreParams function for every new MPC session. Subsequent node restarts simply unmarshal the cached JSON blobs, reducing session startup time from minutes to milliseconds.

Where are the pre-parameters stored?

The parameters are stored as JSON-encoded values in the node’s persistent KV store under the keys pre_params_0 and pre_params_1. This storage is handled in pkg/mpc/node.go (lines 33‑48) and persisted via the Badger database implementation found in pkg/kvstore/badger.go.

How does resharing select the correct pre-parameter set?

During resharing operations, the node uses version-aware selection logic at lines 351‑359 of pkg/mpc/node.go. It calculates version % 2 to index into the ecdsaPreParams slice, ensuring that even and odd key versions use separate parameter sets to maintain cryptographic isolation between resharing rounds.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →