MPCium es un motor MPC seguro y altamente resiliente

Mpcium es un framework de alto rendimiento escrito en Go que implementa esquemas seguros de firma distribuida por umbral mediante computación multipartita (MPC, Multi-Party Computation). A diferencia de los sistemas criptográficos tradicionales que almacenan las claves privadas en un único lugar, Mpcium distribuye fragmentos de la clave privada entre varios nodos independientes y requiere la cooperación de un número mínimo (umbral) de esos nodos para realizar operaciones criptográficas como la firma de transacciones.

Esta arquitectura ofrece:

  • Mayor seguridad: no existe un único punto de compromiso
  • Confianza distribuida: no es necesario confiar en ninguna entidad individual
  • Tolerancia a fallos: el sistema sigue operativo aunque algunos nodos fallen
  • Preservación de la privacidad: ningún nodo posee la clave completa

En su núcleo criptográfico, Mpcium integra tss-lib, una biblioteca de esquemas de firma por umbral de nivel productivo desarrollada por Binance. Admite:

  • ECDSA (secp256k1): Bitcoin, Ethereum, BNB, Polygon y cadenas L2 compatibles con EVM

  • EdDSA (Ed25519): para Solana, Polkadot, Cardano y otras blockchains modernas

Documentación de la arquitectura

Arquitectura del clúster de MPCium
Click to open the full-size diagram

👉 Documento detallado de la arquitectura

Umbral y nodos

Mpcium usa un esquema de umbral t de n para generar claves privadas y firmar con ellas de forma segura.

  • n = número total de nodos MPC (partes de la clave)
  • t = número mínimo de nodos necesarios para firmar

Solo necesitan participar t de los n nodos: la clave privada completa nunca se reconstruye.

Para mantener la seguridad frente a nodos comprometidos, Mpcium exige:

t ≥ ⌊n / 2⌋ + 1

Ejemplo: umbral de 2 de 3

  • ✅ node0 + node1 → firma correctamente
  • ✅ node1 + node2 → firma correctamente
  • ❌ node0 solo → no hay suficientes partes

Esto garantiza:

  • Ningún punto único de compromiso
  • Tolerancia a fallos si algunos nodos se desconectan
  • Seguridad configurable ajustando t y n

Arquitectura

Descripción general

Cada nodo de Mpcium:

  • Guarda una parte de la clave en almacenamiento local cifrado con AES-256 (mediante Badger KV)
  • Participa en la firma por umbral usando tss-lib
  • Se comunica a través de una capa de mensajería resiliente con NATS
  • Se registra en Consul para el descubrimiento de servicios y las comprobaciones de salud
  • Verifica los mensajes entrantes mediante autenticación mutua basada en Ed25519

Flujo de mensajes y verificación de firmas

  1. Una solicitud de firma se difunde al clúster MPC a través de NATS como un evento autenticado. Cada nodo verifica la firma Ed25519 del remitente antes de procesar la solicitud.
  2. NATS difunde la solicitud a los nodos MPC.
  3. Cada nodo participante verifica:
    • La firma del remitente (Ed25519)
    • La autenticidad del mensaje (no reproducible, sesión única)
  4. Si el nodo está en buen estado y dentro del quórum (t):
    • Calcula una firma parcial usando su parte
    • Publica el resultado de vuelta a través de NATS
  5. Una vez recibidas t firmas parciales, se agregan en una firma completa.

Propiedades

  • Ningún punto único de compromiso: las claves nunca se ensamblan por completo
  • Resiliencia bizantina: solo se requieren t de n nodos para continuar
  • Escalable y extensible: amplía fácilmente el clúster o integra herramientas adicionales
  • Autenticación segura entre pares: todos los mensajes entre nodos se firman y verifican con Ed25519

Instalación y ejecución

Vista previa de uso

Iniciar nodos

$ mpcium start -n node0
$ mpcium start -n node1
$ mpcium start -n node2

Implementaciones de cliente

Cliente


import (
    "github.com/fystack/mpcium/client"
    "github.com/nats-io/nats.go"
)


func main () {
	natsConn, err := nats.Connect(natsURL)
	if err != nil {
		logger.Fatal("Failed to connect to NATS", err)
	}
	defer natsConn.Close()
	mpcClient := client.NewMPCClient(client.Options{
		NatsConn: natsConn,
		KeyPath:  "./event_initiator.key",
	})
	err = mpcClient.OnWalletCreationResult(func(event mpc.KeygenSuccessEvent) {
		logger.Info("Received wallet creation result", "event", event)
	})
	if err != nil {
		logger.Fatal("Failed to subscribe to wallet-creation results", err)
	}

	walletID := uuid.New().String()
	if err := mpcClient.CreateWallet(walletID); err != nil {
		logger.Fatal("CreateWallet failed", err)
	}
	logger.Info("CreateWallet sent, awaiting result...", "walletID", walletID)
}