Skip to content

Make ECDSA the primary signature scheme for new Miden multisig accounts #397

Description

@zeljkoX

Context

Falcon (falcon512_poseidon2) should become a second-class signature scheme for Guardian accounts and cosigners:

  • Falcon signing and verification are significantly slower than ECDSA, including in production benchmark results.
  • Post-quantum security is not currently required for this use case.
  • Hosted signers such as AWS KMS support secp256k1 ECDSA but not Falcon. Falcon ACK keys therefore cannot move behind the hosted signer boundary.

Falcon remains supported for existing accounts and explicit opt-in use. This issue changes defaults, APIs, examples, and positioning—not protocol support.

Important compatibility constraint

The signature scheme is selected when a multisig account is created and is effectively permanent.

It determines:

  • which auth MASM component is compiled into the on-chain account;
  • the signature-scheme selector stored in the account;
  • whether Guardian stores Auth::MidenFalconRpo or Auth::MidenEcdsa;
  • how cosigner requests and proposal signatures are verified;
  • which Guardian ACK key signs accepted deltas.

SwitchGuardian changes the Guardian endpoint/key commitment within the account’s existing scheme. It does not convert a Falcon account into an ECDSA account.

There is currently no in-place Falcon-to-ECDSA account migration.

Current defaults

Surface Current behavior Location
TypeScript account builder Missing signatureScheme selects Falcon packages/miden-multisig-client/src/account/builder.ts
Rust contract config MultisigGuardianConfig::new initializes Falcon crates/contracts/src/multisig_guardian.rs
Rust multisig builder generate_key() generates Falcon; ECDSA is explicitly named crates/miden-multisig-client/src/builder.rs
Rust signer alias GuardianKeyStore aliases FalconKeyStore crates/miden-multisig-client/src/keystore.rs
Demo CLI Empty scheme selection chooses Falcon examples/demo/src/main.rs
Browser examples Local signer and session defaults select Falcon examples/_shared/multisig-browser, examples/web, examples/smoke-web
Benchmarks Default authentication scheme is Falcon crates/server/bench/loadgen/src/config.rs
Documentation Published quickstarts generally introduce Falcon first SDK and package READMEs
/pubkey Missing or unrecognized scheme resolves to Falcon server HTTP and gRPC APIs

The server otherwise follows the registered account’s scheme: authentication dispatches from stored metadata, and ACK signing uses that same scheme.

Decision

  • ECDSA becomes the recommended scheme and the default in first-party account-creation workflows.
  • Low-level public APIs should prefer explicit scheme selection because the choice is permanent.
  • Falcon remains available through explicitly named APIs and configuration.
  • Existing Falcon accounts must continue to work without migration or operator intervention.
  • The server must continue loading and serving the Falcon ACK identity while Falcon accounts may exist.

Scope

1. Documentation and positioning

  • Update docs/MULTISIG_SDK.md to lead with EcdsaSigner and generate_ecdsa_key().
  • Update published package/crate READMEs:
    • crates/client/README.md
    • crates/miden-multisig-client/README.md
    • packages/guardian-client/README.md
    • packages/miden-multisig-client/README.md
  • Update relevant example READMEs.
  • Add a concise scheme-selection section to docs/CONCEPTS.md.
  • Describe Falcon as:
    • fully supported;
    • slower than ECDSA;
    • unavailable through hosted signer/KMS backends;
    • recommended only when specifically required.
  • Document that signature schemes cannot currently be migrated in place.
  • Document that removing or changing the Falcon ACK key can strand existing Falcon accounts.
  • Recommend AWS KMS for the ACK identity of new production ECDSA deployments.
  • Retain the existing warning that moving an established ECDSA deployment to a different KMS key changes its Guardian identity and requires SwitchGuardian.

2. First-party defaults

  • Change the demo CLI’s default scheme to ECDSA while retaining an explicit Falcon option.
  • Change the web example’s local active scheme to ECDSA.
  • Change smoke-web session defaults to ECDSA.
  • Change benchmark defaults to ECDSA while retaining explicit Falcon and mixed-scheme profiles.
  • Ensure new-account flows request the Guardian commitment using an explicit scheme rather than relying on /pubkey omission behavior.
  • Continue exercising Falcon in tests, smoke flows, and benchmarks.

3. TypeScript SDK

  • Make MultisigConfig.signatureScheme mandatory in the low-level account builder.
    • The account scheme is permanent and should not be selected through an implicit low-level fallback.
    • Treat this as a breaking SDK change and call it out in release notes.
  • Make first-party/high-level creation flows explicitly pass ecdsa.
  • Keep FalconSigner exported and supported.
  • Update builder tests to cover explicit ECDSA and Falcon account creation.
  • Do not change the imported-proposal fallback where a missing serialized scheme means Falcon. That fallback represents legacy Falcon data, not a new-account default.

4. Rust SDK and contracts

  • Add explicitly named Falcon builder methods:
    • generate_falcon_key()
    • with_falcon_secret_key(...)
  • Deprecate the ambiguous historical methods while preserving their Falcon behavior:
    • generate_key()
    • with_secret_key(...)
  • Deprecate GuardianKeyStore = FalconKeyStore in favor of explicit FalconKeyStore and EcdsaGuardianKeyStore names.
  • Update all first-party Rust creation flows and quickstarts to use generate_ecdsa_key().
  • Keep MultisigGuardianConfig::new behavior compatible during the current release line.
  • Consider making the contract-level scheme mandatory in the next coordinated breaking release rather than silently changing the meaning of MultisigGuardianConfig::new.

5. Server compatibility

  • Retain both Falcon and ECDSA in AckRegistry.
  • Retain Falcon request, lookup, proposal-signature, and ACK verification paths.
  • Retain existing Falcon metadata and storage behavior.
  • Do not remove Falcon secret provisioning from current Terraform/ECS deployments.
  • Keep /pubkey without a scheme returning Falcon for legacy clients.
  • Require new and updated first-party clients to pass the scheme explicitly.
  • Confirm GET /dashboard/info continues exposing:
    • both supported ACK schemes;
    • miden_falcon and miden_ecdsa account counts.

Why Falcon must not be disabled server-side by default

Existing Falcon accounts:

  • have Falcon auth MASM compiled into the on-chain account;
  • authenticate through stored Auth::MidenFalconRpo metadata;
  • require Falcon cosigner signatures;
  • receive Falcon Guardian ACKs;
  • pin the deployment’s Falcon Guardian commitment.

Disabling Falcon verification, ACK signing, or key provisioning would prevent these accounts from submitting and executing deltas. They could not use SwitchGuardian to become ECDSA accounts because that operation preserves the account’s existing signature scheme.

A server default that becomes ECDSA-only would therefore create an unsafe upgrade path for existing deployments.

Follow-up: optional Falcon registration/provisioning

A separate issue may add an operator-controlled policy such as GUARDIAN_ALLOWED_ACCOUNT_SCHEMES.

Such a policy should:

  • default to falcon,ecdsa for upgrade compatibility;
  • apply only to first-time account registration;
  • allow existing Falcon accounts to continue operating;
  • distinguish first-time configuration from reconfiguration;
  • report the effective policy through the operator dashboard;
  • prevent Falcon ACK provisioning from being disabled while stored Falcon accounts exist;
  • avoid Terraform changes that silently remove Falcon support during an ordinary upgrade.

Fresh, verified ECDSA-only deployments could then opt out of provisioning a Falcon ACK key.

Out of scope

  • Removing Falcon implementations, dependencies, or MASM contracts.
  • Disabling Falcon at server startup.
  • Automatically converting existing Falcon accounts to ECDSA.
  • Changing the legacy proposal-import fallback.
  • Changing EVM behavior, which is already ECDSA.
  • Changing operator dashboard authentication, which is independently Falcon-only. ECDSA operator authentication should be handled in a separate issue.

Acceptance criteria

  • New first-party CLI, browser, smoke, documentation, and benchmark flows use ECDSA unless Falcon is explicitly selected.
  • Low-level TypeScript account creation requires an explicit scheme.
  • Rust exposes clearly named ECDSA and Falcon builder methods.
  • Ambiguous Rust Falcon methods remain behaviorally compatible while deprecated.
  • Published SDK documentation leads with ECDSA and explains Falcon’s status.
  • Existing Falcon accounts can still authenticate, create/sign proposals, execute transactions, and receive valid Falcon ACKs.
  • Existing ECDSA accounts remain unaffected.
  • /pubkey omission behavior remains compatible, while first-party clients no longer rely on it.
  • Legacy proposals without a serialized scheme still import as Falcon.
  • Falcon remains covered by automated tests and at least one manual smoke flow.
  • Upgrade documentation explicitly warns operators not to remove the Falcon ACK identity while Falcon accounts exist.

Validation

cargo test -p miden-confidential-contracts
cargo test -p guardian-client
cargo test -p guardian-server
cargo test -p miden-multisig-client

cd packages/guardian-client && npm test
cd packages/miden-multisig-client && npm test
cd examples/smoke-web && npm run typecheck && npm run build
cd examples/web && npm run build

Manual smoke coverage:

  • Create, register, sign, and execute a new ECDSA account through the Rust demo.
  • Create, register, sign, and execute a new ECDSA account through the browser harness.
  • Load and execute against a previously registered Falcon account.
  • Verify Falcon and ECDSA /pubkey responses.
  • Verify accepted deltas carry an ACK matching the account’s scheme.
  • Confirm dashboard account counts and supported ACK schemes remain accurate.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions