Skip to content

RFC: ECDSA / Para Integration Plan for Miden Multisig #23

@rotorship

Description

@rotorship

Target System: Miden Multisig (PSM Architecture)
Goal: Enable users to sign Miden multisig proposals using standard ECDSA wallets (e.g., Para, Privy, MetaMask) instead of being restricted to Miden-native Falcon keys.

Overview

The Private State Manager (PSM) natively supports (or soon to be supported, @MCarlomagno can confirm this) both Falcon512 (Post-Quantum Secure) and ECDSA (secp256k1) tailored for Ethereum compatibility. To allow users to use Para (an embedded wallet provider) or similar ECDSA-based signers, we need to implement an adapter layer in the frontend SDK that bridges these external providers to the PSM's signing interface.

Core Components

1. Frontend SDK: ExternalSignerAdapter

We will introduce an interface in miden-multisig-web-client that abstracts the underlying signer.

// Interface for any signer (Internal Falcon or External ECDSA)
interface MidenSigner {
  getPublicKey(): Promise<string>; // Hex-encoded public key
  getScheme(): 'falcon' | 'ecdsa';
  signHash(hash: string): Promise<string>; // Returns hex-encoded signature
}

An adapter for Para/Ethers would look like this:

class EcdsaExternalAdapter implements MidenSigner {
  private provider: EIP1193Provider;
  private address: string;

  constructor(provider: EIP1193Provider, address: string) {
    this.provider = provider;
    this.address = address;
  }

  async getPublicKey(): Promise<string> {
    // For ECDSA, we need the full public key, not just the address.
    // We might need a signature to recover it if the provider doesn't expose it directly.
    return recoverPublicKeyFromSignature(await this.signHash("0x...dummy..."));
  }

  getScheme(): 'falcon' | 'ecdsa' {
    return 'ecdsa';
  }

  async signHash(hash: string): Promise<string> {
    // Miden expects raw r,s (and potentially v) in a specific serialization
    // EIP-191 signing might limit what we can sign directly.
    // We need to ensure the hash is signed as raw bytes or map it to EIPC-712.
    const signature = await this.provider.request({
      method: 'personal_sign',
      params: [hash, this.address],
    });
    return serializeMidenEcdsa(signature);
  }
}

2. PSM Backend Configuration

The PSM's state_manager.proto already defines MidenEcdsaAuth.

message AuthConfig {
  oneof auth_type {
    MidenFalconRpoAuth miden_falcon_rpo = 1;
    MidenEcdsaAuth miden_ecdsa = 2; // WE USE THIS FOR PARA
  }
}

message MidenEcdsaAuth {
  repeated string cosigner_commitments = 1;
}

3. Workflow: Registration with Para

  1. User Login: User logs in with Para (email/social).
  2. Key Extraction:
    • The frontend requests a signature on a standard message to recover the user's full secp256k1 public key.
    • Para/Metamask usually exposes the address, but Miden needs the public key to verify authentication within the VM.
  3. Account Creation:
    • The MidenEcdsaAuth config is created using this public key.
    • The account is registered with the PSM.

4. Workflow: Signing a Proposal

  1. Proposal: A transaction is proposed. The SDK calculates the TransactionSummary hash (e.g., 0x123abc...).
  2. Signing:
    • The SDK prompts the Para wallet to sign this hash.
    • Challenge: Standard EVM wallets prefix messages (\x19Ethereum Signed Message:\n...).
    • Solution: The Miden VM (or the specific account implementation) must support verifying signatures with this prefix, OR we use eth_sign (dangerous/deprecated), OR we use EIP-712.
    • Preferred Approach: Use EIP-712 Typed Data signing.
      • Domain: Miden Multisig
      • Message: { proposalHash: "0x..." }
      • The Miden account code must be able to hash this struct similarly to verify.
    • Alternative (Simpler): If the Miden ECDSA kernel only verifies raw secp256k1 signatures on the hash, we must ensure the signer output matches.
  3. Submission:
    • The signature is sent to the PSM via SignDeltaProposal.
    • The PSM checks MidenNetworkClient::validate_credential -> MidenAccountInspector.

Implementation Checklist

  • Frontend:
    • Add ethers dependency for ECDSA utilities.
    • Create ParaSignerAdapter implementing the Signer interface.
    • Implement public key recovery from a signature
  • PSM Updates (Verification):
    • Verify if MidenNetworkClient correctly handles the specific serialization of signatures produced by personal_sign or EIP-712.
    • If Miden's stdlib ECDSA verification expects a raw 64-byte signature (r, s), but personal_sign produces 65-byte (r, s, v), we need to slice it in the adapter.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions